Firebase Advent Calendarトリなのに地味な内容で恐縮なんですが、Cloud Functions for Firebase(以下Functionsと呼びます)のデバッグ方法についてまとめてみました。
ログについて
まず最初にFunctionsでのログの見方・出し方をご紹介します。
見方
以下の3通りの方法があります。
- Webコンソールで見る
- functions:logs
- Stackdriverで見る
丸投げですがこちらのトピックに関しては既にAdvent Calendarに記事があったので貼っておきます。
Cloud Functions for Firebase のログをコマンドラインで確認する
出し方
そもそもFunctionsのログは関数が実行された時にデフォルトで
- いつ実行したか
- いつ実行が終了したか。終了するまでに何msかかったか
- ランタイムエラーが起きた時のスタックトレース
をログに書いてくれます。
こんな感じです。
それに加えて任意のタイミングでログを出したい場合には console.xxx
を使うことができます。Functionsのログのログレベルは error
, info
, debug
の3種類があり、それを出し分けることができます。
試しに console.xxx
でどんなログが出るか試してみました。結果としてはこんな感じ↓
ログレベル | |
---|---|
console.log() | info |
console.warn() | error |
console.info() | info |
console.error() | error |
あんまり使い分けるメリットもなさそうなので console.log
と console.error
だけ覚えておけば良いと思います。
ちなみに console.debug()
はクラッシュしてしまいました。ログレベル デバッグ
はデフォルトのログ以外にどうやれば出すことができるのか分からないですが、まあそんな感じです。
###ちなみに
ログに色はつきませんでした。残念。
console.log("%c黄色になるかな?", "color: yellow;");
###参考
デバッグ方法1: ローカルでHTTPベースの関数を実行する
それではデバッグ方法について見ていきます。まずは定番?の firebase serve
。
firebase serve
コマンドを使うことによってローカルで関数がHTTP経由で叩けるようにします。
例えばこんな関数があるとして
exports.hello = functions.https.onRequest((request, response) => {
response.status(200).send('whatsup!');
});
firebase serve --only functions
というコマンドを実行すると
http://localhost:5000/your-firebase-proj/region/hello
という風にUrlが表示されるはずなので、あとはそのUrlにリクエストを送るだけで関数が実行されます。ログなどもローカルのCLIに表示されるので、それを駆使してデバッグに役立てることができるでしょう。
ただ、この方法はHTTPベースで実行できる関数に対しては有効ですが、データベースのアップデートなどイベントに対するトリガー関数に関してはテストできません。
このためお手軽ではありますが、用途が限られた手法ではあります。
デバッグ方法2: Cloud Functions シェルを利用する
対話形式でローカルで関数を実行できるシェルです。HTTP関数以外のRealtime Database、pub/sub、Firestoreなんでもエミュレートできるので非常に便利です。ログもちゃんとCLI上に吐き出してくれます。
早速使い方なんですが、Realtime Databaseに入ってきたテキストを自動的に大文字に変換する関数を例にご説明します。
exports.makeUppercase = functions.database.ref('/messages/{pushId}/original').onCreate(event => {
const original = event.data.val()
console.log('Uppercasing', event.params.pushId, original)
const uppercase = original.toUpperCase()
return event.data.ref.parent.child('uppercase').set(uppercase)
})
それではエミュレーターを立ち上げてみましょう!以下のコマンドをCLIで実行します。
firebase experimental:functions:shell
そして Uppercase("foo")
を入力して実行してみます。コンソールを見たらしっかり大文字になったものが反映されていました。
また、パラメータである pushId
も自動で作ってくれていますね。このパラメータは自分でつけるようにすることもできるみたいです。
makeUppercase('foo', {params: {pushId: 'custom_push_id'}})
ちなみにこのシェルは一々再起動しなくても、関数を編集した内容を保存したら反映されます。準備もほとんどかからず大変便利ですね。
他にも個人的によく使いそうだなと思ったものを以下にまとめます。
HTTP関数
####メソッドを指定
myHttpsFunction() //何も指定しない場合はGETになります
myHttpsFunction.get()
myHttpsFunction.post()
パスやクリパラメータの指定
クエリパラメータをつけたりもできます。
myHttpsFunction("/path")
myHttpsFunction("?test=hogehoge")
Realtime Databaseトリガー
onUpdate や onWrite時に実行
myDatabaseFunction({before: 'old_data', after: 'new_data' })
認証を書き換え
myDatabaseFunction('data', {auth: {admin: false}} //認証されていないユーザとして実行
myDatabaseFunction('data', {auth: {variable: {uid: 'abcd'}}} //特定のユーザのIDを指定
その他にも色んなユースケースに対応しています。詳しいメソッドや引数の説明についてはこちらのドキュメントを読んでみてください。
ローカルでの関数の実行
###参考
https://developers-jp.googleblog.com/2017/10/testing-functions-locally-with-cloud.html
感想
Functionsシェルがかなりいい感じですね。使い慣れれば強力なお供になってくれそうです。一々デプロイして試すのも中々にめんどくさいのでよろしければ一度お試しください!