Cloud Functions × Firestore × Firebase Cloud Messaging
Cloud Functionsはサーバレスコンピューティングサービスです。様々なイベントをトリガーにしてアクションを実行することができ非常にコストパフォーマンスに優れています。
今回はこのCloud Functionsを用いてFirestoreにデータが追加されたら特定のデバイスにpush通知が届くようにします。
Structure
通知を送信したいDBを設計します。今回は簡略化のためにnotifications
というコレクションにしています。
ここであらかじめテーブルにデバイスのidが紐付いているとやりやすいと思います。
notifications
│
├── notification
│ ├── text
│ └── users
. ├── bJi8iJLw0ufF1HCO17v3b7UTVS53
. .
. .
Architecture
Steps
以下のことが既に完了している前提で実装していきます。多分この記事にたどり着くような人はコーディングで行き詰まった人だと思います。Firestoreのサンプルがここしかなかった。。。
- Firebaseプロジェクトは作成済み
- 必要なパッケージはインストール済み
- クライアント側のリモート通知設定済み
1. Cloud Functionsをスタートする
まずプロジェクトを作成します
$ Firebase init
functionsディレクトリ内にあるindex.js
にコードを記述していきます。
2. コードを記述
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.sendNotifications = functions.firestore.document('notifications/{notificationId}').onCreate(
async (snapshot) => {
// Notification details.
const newValue = snapshot.data();
const payload = {
notification: {
title:"新規ライブ",
body: newValue.text + "の新しいライブが追加されました!",
content_available: 'true',
sound: "default",
click_action: `https://${process.env.GCLOUD_PROJECT}.firebaseapp.com`,
}
};
const userIDs = newValue.users
// Get the list of device tokens.
userIDs.forEach(function (value) {
admin.firestore().collection('fcmTokens').doc(value).get()
.then(function (querySnapshot) {
let fcmToken = querySnapshot.data().fcmToken
admin.messaging().sendToDevice(fcmToken, payload);
return;
}).catch(error => { return });
});
});
なんやこれポイント
サンプルに const allTokens = await admin.firestore().collection('fcmTokens').get();
ってあったのでてっきりFirestoreのfcmToken勝手にここに格納されてるのかと思いきや自分でDBつくるっぽかった。なので、userIdと紐付けて識別できるようにしました。
fcmTokens
│
├── fcmToken(id: uid)
│ └── fcmToken
.
.
まずfunctions.firestore.document()
の引数にコレクションを指定します。今回はテーブルに新たなドキュメントが追加されたときに発火するようにしたいのでonCreate()
を呼び出しています。
その他にもonUpdate()
、onDelete()
などさまざまなトリガーがあります。詳しくはこちら。
そして、payload
に通知の設定をします。
fcmTokens
というコレクションからfcmtokenをゲットすることができます。RealtimeDBより便利な気がする。
最後にsendToDevice()
で取得したユーザのトークンにまとめてpush通知を送信しています。
3. Deploy
$ firebase deploy
なんか死んでたらログを確認してちょこちょこ直していきましょう。
4. Test
ためしにPythonからFirestoreに新しいドキュメントを追加してみます
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore
cred = credentials.Certificate()
firebase_admin.initialize_app()
db = firestore.client()
notification_data = {
"text": "MY FIRST STORY",
"users": ["gHrdAxQhFYdTmoFjgi8RX8PljXv1"]
}
db.collection(u'notifications').document().set(notification_data)
任意のデバイスにpush通知が来ればオッケー。たっくーTV見てたのは内緒。
コードはこちら