はじめに
Cloud Functions for FirebaseはFirebase向けのCloud Functionsである。Cloud Funcsionsと同様、現在ベータ版で提供されている。
できること、使い方はほぼCloud Functionsと変わらないように見えるが、
Google Cloud Functions と Firebaseを見るかぎりでは、Firebase Realtime Databaseや、Firebase Authentication、Firebase Cloud Firestoreのトリガが追加提供されていたり、「Google Cloud Functions と Firebase SDK for Cloud Functions には、完全な相互運用性があるわけではありません。」などと記述があるのでFirebase向けに最適化されたFuncsionsという位置づけなのだろう。
とりあえず試したいことがあったので、Firebase FunctionsでCloud PubSubをトリガしてみる。
やってみる
GetstartedとCloud Pub/Sub トリガーのページを参考にやってみた。
Getstartedによると、Cloud Functionsは現時点でNode v.6.11.5
を実行する。なので、ローカルの環境に6.11.5をインストールしたほうがいい。v8.0.0でdeployしたときはエラーが出たので。
例えばnodebrewの場合は以下のようにする。
nodebrew install-binary v6.11.5
nodebrew use v6.11.5
まず、Firebase コンソールに移動してプロジェクトを作成する。
今回は Firebase Cloud Firestoreを使ってみる のときに使った btf-test-firestore
が残ってたのでそれを使うことにした。
プロジェクトに移動して左側メニューの Functions をクリックしてFuncsionsのダッシュボードに移動する。まだ何もない。
ターミナルを開いて、firebase-tools をグローバルインストールする。
npm install -g firebase-tools
Firebase CLIでログインを実行する。ブラウザが開くので、ログイン認証をし、CLIに戻って正常にログインされたことを確認する。
firebase login
適当なディレクトリを作って移動し、Funcsionsのプロジェクトを作成する。
プロジェクト名を聞かれるのでFunctionsを設定したいプロジェクトを指定する。今回は btf-test-firebase
言語はJavaScriptかTypeScriptを選べる。今回はJavaScript
ESLintを入れる Yes
npm installを実行する Yes
mkdir firebase-functions-pubsub-test && cd $_
firebase init functions
❯ btf-test-firestore (btf-test-firestore)
❯ JavaScript
? Do you want to use ESLint to catch probable bugs and enforce style? Y
? Do you want to install dependencies with npm now? Y
プロジェクトの設定が完了したら ./functions/index.js
を開いて以下のように更新する。
functions.pubsub.topic('topic-btf').onPublish()
がPubSubをトリガする関数のようだ。topic-btf
の部分は後でパブリッシュする任意のトピック名を指定する。
const functions = require('firebase-functions');
exports.helloPubSub = functions.pubsub.topic('topic-btf').onPublish(event => {
const pubSubMessage = event.data;
// Get the `name` attribute of the PubSub message JSON body.
let name = null;
try {
name = pubSubMessage.json.name;
console.log(`Name: ${name}`);
} catch (e) {
console.error('PubSub message was not JSON', e);
}
return 0;
});
ちなみに、上記のサンプルコードはCloud Pub/Sub トリガーに書いてあるサンプルの行末に return 0
を加えている。現時点ではこうしないと、Functionsが実行された時に Function returned undefined, expected Promise or value
という警告がログに表示される。なのでこちらなどを参考にreturn 0
を追加した。
試した感じでは return true
でも警告が出たので、数値や文字列値じゃないとダメなのかもしれない。
index.js
が更新できたら、デプロイを実行する
firebase deploy --only functions
=== Deploying to 'btf-test-firestore'...
i deploying functions
Running command: npm --prefix "$RESOURCE_DIR" run lint
> functions@ lint /[USER DIR]/firebase-functions-pubsub-test/functions
> eslint .
✔ functions: Finished running predeploy script.
i functions: ensuring necessary APIs are enabled...
✔ functions: all necessary APIs are enabled
i functions: preparing functions directory for uploading...
i functions: packaged functions (42.39 KB) for uploading
✔ functions: functions folder uploaded successfully
i functions: creating function helloPubSub...
✔ functions[helloPubSub]: Successful create operation.
✔ Deploy complete!
Project Console: https://console.firebase.google.com/project/btf-test-firestore/overview
デプロイが成功したらFirebase Functionsのダッシュボードに helloPubSub が表示される。
gcloudコマンドでトピックにパブリッシュする。topic-btf
はindex.js
で指定したトピック名。--message
でFunctionsでサブスクライブしたメッセージのJSONを指定する。--project
でFunctionsを設定したプロジェクトIDを指定する。うまくいくとMessage IDが返ってくる。
gcloud pubsub topics publish topic-btf --message '{"name":"BathTimeFish"}' --project btf-test-firestore
messageIds:
- '59076465449285'
このコマンド、Cloud Pub/Sub トリガー では現時点で gcloud beta pubsub topics publish new_topic 'MyMessage'
と書いてあってちょっと古い。オプションの指定の仕方がbetaのときと変わっているようだ。
Firebase Functions コンソールの ログ タブをクリックして正常に実行されているかを確認する。
ちゃんとevent.data.name
が表示されているようだ。
テストし終わったFunctionを削除する。が、ちょっとめんどい。現時点でFirebase Functionsコンソール上ではFunctionsを削除する機能が提供されておらず、firebase CLIコマンドにも削除するコマンドが存在しない。stackoverflowあたりでも困ってる人を見かける。
結論から言うと、GCPのほうのダッシュボードからなら削除できる。Firebase Cloud Function の関数を削除する というズバリな記事を参考にさせていただき、削除することができた。
まずGCPプロジェクト ダッシュボードにアクセスして、選択 をクリックする。
Functionsのあるプロジェクトをクリックする。今回は btf-test-firestore
プロジェクトのダッシュボードに移動するので リソース ペインの Cloud Functions をクリックする。
先ほど作成した helloPubSub
の右側オプションメニューから 削除 をクリックする
削除 をクリックする
Firebaseのコンソールにもどってみると、helloPubSub
が消えているのが確認できる。
まとめ
そのうちFirebase側からも削除できるようにしてもらいたいが、とりあえず特にハマりどころもなく実行することができた。
これでスケーラビリティ考えずにPubSubできて実験レベルではほぼ無料で考えていいというのはすばらしいと思う。Firebase側にFunctionsがあるとHostingやCloud Messaging、Cloud Firestoreなんかにつなげる設計も直感的に開発しやすくなる気がする。FirebaseだけでもAWSやAzureでやるようなサーバレスはけっこうできますね。