FirebaseのCloud Functions + Firestoreでプッシュメッセージを送る

logo_firebase

Firebase でプッシュ通知を送る方法は色々ありますが、大した処理がないので今回はサクッとサーバーレスで Cloud Functions にデプロイします。

データベースは Realtime Database もありますが、今回は Firestore を使いたいと思います。

仕様概要

  • 打刻アプリの初期設定で Firebase へユーザのデバイストークンを登録
  • 通知の設定が有効で出勤時間の 10 分前で未打刻ならプッシュリマインダーを投げる
  • 処理の内容は Cloud Functions に Node.js でデプロイし、生成された URL を社内サーバからcronで叩く

構築

Firestore

users
|- id
|- fcmToken
|- isEnabled
|- isClockedIn

Firestore のユーザデータはシンプルにトークン、設定、打刻のみです。

環境

Vagrant/Ubuntu Xenial/Node.js 8

Cloud Functions は Node.js で簡単に処理をデプロイできます。Node LTS 10 を使いたいところですが、Firebase のランタイムが 8 までなので、今回は 8 で合わせました。

Xenial で普通にapt-getnodejsを入れると古いバージョンしか入らないのでご注意を。

Firebase SDK

Node と npm が入ったところで、Firebase SDK をグローバルインストールします。

$ npm install -g firebase-tools

Firebase アカウントログイン

コマンドの後アノニマスデータを Firebase に送信していいか聞かれるので y/n を入力。表示された URL をブラウザで開いて Firebase のコンソール上でログイン認証。

$ firebase login

Firebase Functions

アプリ用の directory を切ってその中でinitします。JavaScript か TypeScript を選べるので好きな方を選びます。勝手にファイル/ディレクトリが生成されるので、functions ディレクトリの中で firebase のモジュールをインストールします。

$ mkdir APP_DIR
$ cd APP_DIR
$ firebase init functions
$ cd functions
$ npm i -s firebase-functions@latest firebase-admin@latest

Node のランタイムはデフォルトで 14 なのですが、14, 12, 10 が選べるので 12 にしたい場合はfunctions/package.jsonに追記します。階層は”dependencies“などと一緒です。

// package.json
{
// ...
"engines": { "node": "12" }
// ...
}

ロジック

firebase-adminを初期化します。

実装したい function は『exports.エンドポイント』の形で書きます。このファンクション名がそのままエンドポイントになります。

Promiseチェーンを書いていくことになりますが、最初にトリガーするイベントを選びます。url を叩く度に起動するならfunctions.http.onRequest()、Realtime DB のイベントでトリガーするならfunctions.database.ref().onEVENT()、Firestore ならfunctions.firestore.document().onEVENT()などでチェーンを始めます。(詳しくはこちら)

Firestore のインスタンスを取得するには、admin.firestore()で取得し、collectionを選択、get()でスナップショットを取得します。ここで返ってくるスナップショットでforEachを回してdocumentを取りに行きます。id はそのまま.id で取得できますが、データはdata()で取得し、あとはそれぞれのキーで内容を取得します。

通知設定が有効で、まだ打刻しないユーザのトークンを配列に詰め込んでいきます。

トークンが集まったところで、admin.messaging()sendToDevice()を使ってプッシュ通知を送っていきます。第一引数はトークンの String 配列、第二引数にペイロードを渡します。

結果のオブジェクトがPromiseで渡ってくるので、中身を見てエラーがないか確認します。(特に処理は入れてませんが、エラーコードを見てトークンが無効になっていた場合などは削除するなどの処理を入れます。)

レスポンスは特に返す必要はないですが、、一応返しています。Node.js のhttpsですので、同じようにResponseオブジェクトで返します。

全体像はこんな感じです。

デプロイ

デプロイは Firebase SDK のコマンド一発で行います。アカウントに権限があることを確認してください。

$ firebase deploy --only functions --project PROJECT_ID

URL が表示されれば成功です。コンソール上からもファンクションがデプロイされているのが確認できます。curl やブラウザで URL にアクセスすると、処理が走ってプッシュ通知が送られてきます。

github のレポジトリはこちら

参考

COPYRIGHT © 2023 Kohei Ando