Cloud Functions と Firestoreを連携させる
Cloud HostingからFirestoreに連携したので、今度はCloud Functionsから連携してみる。
1.Promise
1.1 以下の動画を参考に試す。まずは、Promiseの約束事を確認。
- 以下の3つの状態を持つ
- PENDING
- FULLFILLED
- REJECTED
- Firebase admin SDKで例えば以下で利用
- データベースの読み書き
- Cloud Strage ファイルの操作
- Cloud Messageでの通知
- ユーザープロファイルの更新
- 安全に終了させる必要がある
- HTTPトリガーでは、最後にResponseを返す
- バックグラウンドトリガーはPromiseを返す
1.2 動画を参考に、Firebase HostingとFIrestoreを試す でとFirestoreに登録したドキュメントを取得してみる
import * as functions from 'firebase-functions'; import * as admin from 'firebase-admin'; export const getSandwichData = functions.https.onRequest((request, response) => { const promise = admin.firestore().doc('sample/sandwichData').get(); promise.then(snapshot => { const data = snapshot.data(); response.send(data); }); });
1.3 Javascriptにコンパイルしlintをかける
まず、上記のコードをコンパイル
> cd functions > npm run-script lint
エラーが発生する
ERROR: 6:5 no-floating-promises Promises must be handled appropriately npm ERR! code ELIFECYCLE npm ERR! errno 2 npm ERR! functions@ lint: `tslint --project tsconfig.json` npm ERR! Exit status 2 npm ERR! npm ERR! Failed at the functions@ lint script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
これは、上記のコードでは、エラー時のハンドリングが記述されていないため。適切に処理するように怒られる。
エラーの処理を追記する。
import * as functions from 'firebase-functions'; import * as admin from 'firebase-admin'; admin.initializeApp(); export const getSandwichData = functions.https.onRequest((request, response) => { const promise = admin.firestore().doc('sample/sandwichData').get(); const p2 = promise.then(snapshot => { const data = snapshot.data(); response.send(data); }); p2.catch(error => { console.log(error); response.status(500).send(error); }); });
1.4 再度コンパイルを実行
> npm run-script lint > functions@ lint C:\workspaces\Gcp-workspace\Firebase\gcp_api_trial\functions > tslint --project tsconfig.json > npm run-script build > functions@ build C:\workspaces\Gcp-workspace\Firebase\gcp_api_trial\functions > tsc
今回は成功。
lib/index.js にJavaScriptにコンパイルされた結果が生成される。
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const functions = require("firebase-functions"); const admin = require("firebase-admin"); admin.initializeApp(); exports.getSandwichData = functions.https.onRequest((request, response) => { const promise = admin.firestore().doc('sample/sandwichData').get(); const p2 = promise.then(snapshot => { const data = snapshot.data(); response.send(data); }); p2.catch(error => { console.log(error); response.status(500).send(error); }); }); //# sourceMappingURL=index.js.map
2.エミュレータで実行
https://firebase.google.com/docs/firestore/security/test-rules-emulator?hl=ja
> firebase setup:emulators:firestore > firebase emulators:start --only firestore
エミュレーターは立ち上がるが、Firestoreのエミュレータがどういう理屈で動作するのか今一つわからないので、実環境へデプロイして確認する。
3.GCP環境へデプロイ
3.1 デプロイと確認
> firebase deploy --only functions
デプロイ時に、表示されるURLにアクセス。Firestoreで登録したデータをJSONで取得できた!OK
3.2 Functions の確認
デプロイしたFunctionsは以下のコマンドで確認。
> gcloud functions list NAME STATUS TRIGGER REGION getSandwichData ACTIVE HTTP Trigger us-central1
削除する場合は以下で行う。
gcloud functions delete {関数名}