# FCMの送信テスト方法(http v1 API版) 雑に補足 - 発行した認証トークンは数時間で期限が切れるので面倒 - 以前のhttpによるテストのほうが楽に行えるが、http v1 への移行が推奨されているのでいずれ使えなくなりそう([参考](https://firebase.google.com/docs/cloud-messaging/migrate-v1?hl=ja)) ## 1. Push通知送信用のエンドポイントを用意する `https://fcm.googleapis.com/v1/projects/your_project_id/messages:send` `your_project_id` にはFirebaseのプロジェクトIDを入力する ![https://i.imgur.com/3DhxWzS.png](https://i.imgur.com/3DhxWzS.png) ## 2. 認証情報を生成する 2-1. 秘密鍵を生成してjsonファイルを入手する ![https://i.imgur.com/1fNiy78.png](https://i.imgur.com/1fNiy78.png) 2-2. 次のスクリプトの引数にjsonファイルを渡して実行する。成功すると、クリップボードに認証情報がコピーされる スクリプト ```jsx var request = require('superagent') var crypto = require('crypto') var fs = require('fs') const { exec } = require('child_process') async function generateAccessToken(keyfile) { console.log(`Use ${keyfile}`); var keys = require(`./${keyfile}`); var endpoint = 'https://www.googleapis.com/oauth2/v3/token'; var now = Math.floor( new Date().getTime() / 1000 ); var header = { alg: 'RS256', typ: 'JWT' }; var claims = { iss: keys.client_email, scope: 'https://www.googleapis.com/auth/firebase.messaging', aud: endpoint, exp: now + 3600, // maximum expiry date is 1 hour after the issued time. iat: now }; var body = { assertion: createJWT(header, claims, keys.private_key), grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer', } // send request to get access token var res = await request.post(endpoint) .set('Content-Type', 'application/x-www-form-urlencoded') // you must set this header. .send(body) console.log(res.body) return res.body.access_token } function createJWT(header, claims, private_key) { var encodedHeader = Buffer.from(JSON.stringify(header)).toString('base64'); var encodedClaims = Buffer.from(JSON.stringify(claims)).toString('base64'); var sign = crypto.createSign('RSA-SHA256'); var data = Buffer.from(encodedHeader + '.' + encodedClaims); sign.update(data); signature = sign.sign(Buffer.from(private_key), 'base64'); // JWT format is '{base64 encoded header}.{base64 encoded claims}.{signature}' return [encodedHeader, encodedClaims, signature].join('.'); } async function main() { try { var args = process.argv.slice(2); if (args.length == 0) { throw "ERROR: Firebaseプロジェクトの秘密鍵となるJSONファイルを指定してください"; } var filename = args[0]; if (!filename.endsWith(".json")) { throw "ERROR: JSONファイルを指定してください。Firebaseコンソールの「プロジェクトの設定」を開き、「サービスアカウント」を開くと、新しい秘密鍵を生成できます"; } var token = await generateAccessToken(filename); exec(`printf ${token} | pbcopy`, (err, stdout, stderr) => { if (err) { console.log(`stderr: ${stderr}`) } else { console.log("access token pbcopy succeeded."); } }) } catch (e) { console.log(e); } } main(); ``` 参考: [https://christina04.hatenablog.com/entry/2015/06/04/224159](https://christina04.hatenablog.com/entry/2015/06/04/224159) 実行方法 ``` $npm install superagent(初回のみ) $npm install crypto(初回のみ) $npm install googleapis (初回のみ) $node access_token_generator.js your_json_file.json ``` ## 3. FCMトークンを用意してAPIを叩く ![https://i.imgur.com/PxzCJCM.png](https://i.imgur.com/PxzCJCM.png) ![https://i.imgur.com/1HjycW7.png](https://i.imgur.com/1HjycW7.png) ``` { "message": { "token": "your_fcm_token", "notification": { "title": "雨が降ります", "body": "傘をお持ちください" }, "data": { "some_key": "some_value" }, "android": { "notification": { "click_action": "FLUTTER_NOTIFICATION_CLICK" } } } } ```