# 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"
}
}
}
}
```