今回は Firebase Cloud Messaging
のトピック通知を Functions
経由で登録する方法を紹介していきたいと思います👩🌾
それではやっていく
Node.js
で実装していくので、とりあえず Firebase
の Admin SDK
を導入し、初期化します。
$ npm install firebase-admin --save
const admin = require('firebase-admin'); admin.initializeApp();
今回は notificationSettings
というユーザ個別の通知設定のコレクションにドキュメントが作成された時点で、generalNotification
というトピックに登録していく仕様で実装してみます。そして下記が完成したコードになります。ドキュメントの作成をトリガーに、書き込まれたデータの token
を取得して subscribeToTopic()
でトピックに登録しています。また、region
に関してはデフォルトでは us-central1
にデプロイされてしまうので、asia-northeast1
に変更しています。
const admin = require('firebase-admin'); admin.initializeApp(); const REGION = 'asia-northeast1'; const GENERAL_NOTIFICATION_TOPIC = 'generalNotification'; exports.onNotificationSettingCreated = functions.region(REGION).firestore.document(`notificationSettings/{notificationSettingId}`).onCreate(async (snap, context) => { const value = snap.data().settings.isEnabledForGeneral; const isEnabledForGeneral = [null, undefined].includes(value) ? true : value; const token = snap.data().token; if ([null, undefined].includes(token)) { return console.error('Error message token not found.'); } else if (isEnabledForGeneral) { await subscribeToTopic([token], GENERAL_NOTIFICATION_TOPIC); return; } else { return console.log('The message from the management is rejected.'); } }); async function subscribeToTopic(tokens, topic) { await admin.messaging().subscribeToTopic(tokens, topic) .then((response) => { console.log('Successfully subscribed to topic:', response); }) .catch((error) => { console.error('Error subscribing to topic:', error); }); }
ついでに、トピックの購読を解除する関数も追加してみます。これはドキュメント内の settings.isEnabledForGeneral
という Bool
値が更新された時にハンドリングしたいので下記のように実装します。
exports.onNotificationSettingUpdated = functions.region(REGION).firestore.document(`notificationSettings/{notificationSettingId}`).onUpdate(async (change, context) => { const newData = change.after.data(); const value = newData.settings.isEnabledForGeneral; const isEnabledForGeneral = [null, undefined].includes(value) ? true : value; const token = newData.token; if ([null, undefined].includes(token)) { return console.error('Error message token not found.'); } else { if (isEnabledForGeneral) { await subscribeToTopic([token], GENERAL_NOTIFICATION_TOPIC); return; } else { await unsubscribeFromTopic([tokens], GENERAL_NOTIFICATION_TOPIC); return; } } }); async function unsubscribeFromTopic(tokens, topic) { await admin.messaging().unsubscribeFromTopic(tokens, topic) .then((response) => { console.log('Successfully unsubscribed from topic:', response); }).catch((error) => { console.error('Error unsubscribing from topic:', error); }); }
という感じで本日も以上になります🍺