😎
[FCM] プッシュ通知, チャット, デバイス(ユーザー)間で送り合う
そもそもプッシュ通知っていろんな種類ある
要件 | 例 | 配信方法 |
---|---|---|
1つの端末が1つの端末に送信 | チャット | node環境での配信, Firebase functions |
1つの端末が複数の端末に送信 | グルチャ | node環境での配信, Firebase functions |
1つのトピックをサブスクしている端末らに送信 | コミュニティ, 掲示板 | node環境での配信, Firebase functions |
運営側が複数の端末に送信 | キャンペーンの配信, サービスコンテンツの配信 | Firebase Admin SDK, FCM HTTP v1 API |
送信側と受信側で実装が全く異なる
FCM の実装には、送信と受信のために以下の 2 つの主要コンポーネントが含まれています。
- メッセージの作成、ターゲティング、送信を行う Cloud Functions for Firebase やアプリサーバーなどの信頼できる環境。
- 対応するプラットフォーム固有のトランスポート サービスを介してメッセージを受信する Apple、Android、またはウェブ(JavaScript)クライアント アプリ。
送信側のTL;DR (忙しい人のための"結論")
FCM API(HTTP v1) vs Cloud Functions
①Cloud Functions の利用例
- データベースの特定の値が更新されたら、プッシュ通知を送る
- ユーザがアカウントを削除したことを検知して、削除されたユーザに関連するデータをデータベースから削除する
- その他サービス固有の API を作成する
②GoogleAPI: Firebase Cloud Messaging (HTTP v1) API
RESTで書ける
FCM API(HTTP v1)を検証してみる
Bearer Tokenの(かんたんな)取得の仕方
Node.js: Firebase Admin SDK使ったほうが手っ取り早い?
FCM サーバーとの対話には Firebase Admin SDK または基本的なプロトコルの 2 つの方法があり、どちらを使用するか決定する必要があります。一般的なプログラミング言語で広くサポートされていること、認証や認可を簡単に処理できることから、Firebase Admin SDK を使用することをおすすめします。
functionsを使うパターン
初期package.json
{
"name": "functions",
"scripts": {
"lint": "eslint --ext .js,.ts .",
"build": "tsc",
"build:watch": "tsc --watch",
"serve": "npm run build && firebase emulators:start --only functions",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "18"
},
"main": "lib/index.js",
"dependencies": {
"firebase-admin": "^11.8.0",
"firebase-functions": "^4.3.1"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.12.0",
"@typescript-eslint/parser": "^5.12.0",
"eslint": "^8.9.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-import": "^2.25.4",
"firebase-functions-test": "^3.1.0",
"typescript": "^4.9.0"
},
"private": true
}
functions/index.js
functions/index.js
import {onRequest} from 'firebase-functions/v2/https';
import functions from 'firebase-functions';
import admin from 'firebase-admin';
admin.initializeApp();
export const pushTo = onRequest({ region: 'asia-northeast1' }, (request, response) => {
const title = request.query['title']; // 通知のタイトル
const body = request.query['body']; // 通知の内容
const token = request.query['token']; // 送り先のトークン
// 通知の内容を作る処理
const message = {
notification: {
title: title,
body: body,
},
data: {
title: title,
body: body,
},
android: { // androidの設定
notification: {
sound: 'default',
click_action: 'FLUTTER_NOTIFICATION_CLICK',
},
},
apns: { // iOSの設定
payload: {
aps: {
badge: 1,
sound: 'default',
},
},
},,
"webpush": {
"headers": {
"Urgency": "high"
},
"notification": {
"body": "This is a message from FCM to web",
"requireInteraction": "true",
"badge": "/badge-icon.png"
}
},
token: token,
};
pushToDevice(token, message); // push通知を送る関数に内容を載せて実行
});
// push通知を送る関数
/**
* @param token
* @param payload
*/
function pushToDevice(token, payload) {
admin.messaging().send(payload)
.then((_pushResponse) => {
return {
text: token,
};
})
.catch((error) => {
throw new functions.https.HttpsError('unknown', error.message, error);
});
}
なにこれ。
すんなり、いけてもたやないの。。。
(TypeScriptにするといろいろterminalがうるさいのでJsで良さそうだよ♡)
Discussion
管理画面からテスト送信する