Firebaseとかいうスーパー便利サービスの使い方の一部を紹介します。
Cloud Functions
従来、自分で借りたり用意したサーバー上で動かしていたもろもろの処理を、Firebase上に書いてしまうことができます。
サーバー用意しなくていいし、少量なら無料だし、関数をトリガーも使いやすいものがたくさん用意されています。
今日は、Cloud Functions
を使って、Analytics for Firebase
へのイベントの投稿をトリガーにして、Cloud Firestore
にデータを保存するようなfunctionを書いてみようと思います。
そんなの公式ページにサンプルあるでしょ?
ある…かな?
こちらのCloud Functions で可能な処理には、「Realtime Database(Cloud Firestoreの前身)
へのデータの追加をトリガーにして、その追加されたデータに何かする」という例はありますが、新しいデータをCloud Firestore
に追加する例はパッと見つからなかったです。
コード
いきなりですがコードです。中身については下で順次説明していきます。
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';//※1 Admin SDK について
admin.initializeApp();//※1 Admin SDK について
exports.recordPostedScore = functions.analytics.event('post_score').onLog((event)=>{
const firestore = admin.firestore();//※2 timestampについて
const settings = { timestampsInSnapshots: true };//※2 timestampについて
firestore.settings(settings);//※2 timestampについて
const colref = firestore.collection('scores');
colref.add({
score: Math.round(Number(event.params.score)),
date: new Date(),
device_category: event.user.deviceInfo.deviceCategory,
device_model: event.user.deviceInfo.deviceModel
}).then(docref=>{
console.log("Added ID is: " + docref.id);
}).catch(e=>console.log(e));
});
AdminSDKについて
import * as admin from 'firebase-admin';//※1 Admin SDK について
admin.initializeApp();//※1 Admin SDK について
この部分です。
普段クライアント側でコーディングしてる場合、Firestore
にデータを追加するには、CollectionReferenceとかDocumentReferenceを作成しないといけないのですが、
その辺のことができるのがこのAdmin SDKです。
こちらの公式スタートガイドに書いてあるように、admin.initializeApp();
を実行しておく必要があります。import
の直後にやっておけば間違いないですね。
また、この公式スタートガイドはimport文のかわりにrequire文が書かれており、若干書き方が古いです(2018-12-20現在)。
ターミナルからfirebase init functions
とした場合に作成されるfunctions/src/index.ts
にはこの記事にあるような書き方でimport文が書かれておりましたので、そちらの方が新しくて間違いないと思います。
const firestore = admin.firestore();
const firestore = admin.firestore();
これで、こちらのGoogle Cloudのドキュメントに書いてあるのと同じFirestore client
が得られますので、あとは
colref = firestore.collection('scores');
などとすれば、CollectionReference
が得られるので、クライアント側でプログラミングしてる時と同じように書けます。
admin.firestore()
について詳しくはこちら。→本家リファレンス
timestampについて
Cloud Firestore
に保存するデータのうち、timestamp
型のものは、new Date()
をそのままつっこんではいけないようです。
そのために、こちらの
const firestore = admin.firestore();//※2 timestampについて
const settings = { timestampsInSnapshots: true };//※2 timestampについて
firestore.settings(settings);//※2 timestampについて
下二行のような設定作業が必要になります。
詳しくはこちらのQiita記事がわかりやすかったです。
FirestoreのTimestampの仕様変更による警告と、その対処
paramsとかdeviceCategoryとかの調べ方
あともう一つ困ったことがあったので、それについての話だけして終わります。
リファレンスを見るときは、一つずつ、何型のインスタンスが返るのか確認し、その型の使い方を改めて調べることを繰り返す
ということです。
実際にやってみましょう。
今回は、Analytics for Firebase
へのイベント投稿をトリガーとして、「そのイベントについてきたscore値」「投稿したユーザーのデバイス情報」をCloud Firestore
に保存したいです。
でも、それらの情報が一体どういう形で取得できているのかがわからない!!
ちなみにいきなりですが最終的なコードは以下のようになります。
exports.recordPostedScore = functions.analytics.event('post_score').onLog((event)=>{
//...中略...
colref.add({
score: Math.round(Number(event.params.score)),
date: new Date(),
device_category: event.user.deviceInfo.deviceCategory,
device_model: event.user.deviceInfo.deviceModel
}//...後略...
);
この部分、大枠としてはfunctions.analytics.event(...).onLog(...)
の引数に、ハンドラ関数を渡す、という形をしています。
Analytics for Firebase
へのイベント投稿をトリガーとして呼び出される関数は、こちらの本家の例によると、functions.analytics.event('event_type').onLog((event)=>{});
という書き方をするようなのて、これでいい。
で、そのハンドラ関数の引数に、いろいろな情報が詰まったインスタンスを渡してくれるわけですね。
ところで、そのハンドラ関数の引数はevent
という名前にしてあるわけですが、このevent
には一体何型のインスタンスが渡っているんでしょうか?どう書けばそこから情報を取り出せるのでしょうか?
ということでfunctions.analyticsのリファレンスを見ると、functions.analytics.event(...)
というメソッドは
functions.analytics.AnalyticsEventBuilder
を返すことがわかります。
では、functions.analytics.AnalyticsEventBuilderのリファレンスを見ると、
そこにやっとonLog
メソッドがあって、その返り値はfunctions.CloudFunction
だそうです。なるほど、これでCloud Functions
で実行可能な形になるわけですね。
で、そのonLog
の引数として渡すハンドラ関数の引数は、何型なのかというと、
だそうです。
functions.analytics.AnalyticsEvent
やっとこれでevent
の型がわかりました。
で、
functions.analytics.AnalyticsEventのリファレンスを見るとparams
とかuser
とかのプロパティがあって、その中に今回記録したい情報があるらしいことが、ここまで調べてようやくわかりました。
さらに、user
の中にどんな情報があるかは
functions.analytics.UserDimensionsを見る必要があるし、その中のデバイス情報についてはさらに
functions.analytics.DeviceInfoを見なきゃいけません。そこまで見てやっと返り値がstring or undefined
になります。
サンプルコード一つでポンとわからない場合、この程度のリファレンスの渡り歩きは日常茶飯事ですから、臆せずガンガン調べましょうね〜〜。