岐阜だからさElixir

試していることなど...需要がないけど細々とアウトプットしてます

cloud-function使ってクラウドのDatabaseの値を取得して返す

前回

cloud-functionのデプロイまでを触ってみたの記事で
cloud-functionを使って、元から記述されていたサンプルコードをデプロイするところまで触りました
今回はもう少し面白みのありそうなことをやってみたので記事にしました
こちらの動画を元にやってきます

やること

cloud-functionのセットアップに関しては前の記事をご覧ください
今回はFirebaseのクラウドのDatabaseに保存されている値をGETメゾット使ってAPI経由で取得します
実際の実務でもよくやることなのでcloud-functionだとどれぐらいの手間で作れるのか楽しみですね

APIの作成経験ですが

ぐらいしか触った事がないので最終的にデプロイまでの楽さを比較しようかと思ってます

FirebaseのDatabaseにデータを追加する

Firebaseのプロジェクトページの左メニューの

開発-> Databaseを選択

からDatabaseの編集が可能です

今回はデータを作成(追加)するだけなので

  • コレクションを追加(分かる範囲で適当にネーミング)
  • ドキュメントを追加(同上。適当にフィールドも設定)

こんな感じになってればOKです

f:id:takamizawa46:20190416073608p:plain
Dtabaseにデータを作成完了

cloudのDatabaseからデータをfetchする

特に難しい部分もないので、先にコード全部載せておきます

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin'; //adminをimport

//この1行ないとエラーになるので注意
admin.initializeApp();

//Firebaseから特定パスの情報を取得する
export const fetchCityInfomation = functions.https.onRequest((_request, response) => {
  //doc()に取得先のパスを記述
  admin.firestore().doc('cities-weather/japan-data').get()
    //promiseをthen, catchで処理
    .then(snapshot => {
      const data = snapshot.data();
      response.send(data);
    })
    .catch(error => {
      console.log("error: ", error);
      response.status(500).send(error);
    })
})

はい、たったこれだけです。楽すぎやろ〜
クラウドにデプロイする前にローカルで動作を試してみます
ただコマンド3つ叩くのがだるいので.shファイルにしておきます

./functions/local-test.sh

npm run-script lint #tslintを実行(構文チェック)
npm run-script build #tsをjsにbuild
firebase serve --only functions --project cloud-function-114514 #ローカルでrunserverして動作チェック

全てが問題なくsucsessになるとこんな感じでlocalにapiが立ちます

 ❯  bash local-test.sh

> functions@ lint ./Desktop/firecast/functions
> tslint --project tsconfig.json


> functions@ build ./Desktop/firecast/functions
> tsc


=== Serving from './Desktop/firecast'...

i  functions: Preparing to emulate functions.
Warning: You're using Node.js v10.9.0 but Google Cloud Functions only supports v6.11.5.

##ここに注目!!
✔  functions: getWeatherInfo: http://localhost:5000/cloud-function-114514/us-central1/getWeatherInfo
info: User function triggered, starting execution
info: Execution took 1781 ms, user function completed successfully

記述されたエンドポイントを見に行ってみると...

{"city":"tokyo","temp":23}

うまく取得出来てますね

値を抽出する場合に

response.send(data.city);

とするとundifinedの可能性があるでって怒られるので色々試してみる
三項演算子だとこれで通る

.then(snapshot => {
      const data = snapshot.data();
      const returnStr = data !== undefined ? data.city: null;
      response.send(returnStr);
    })

ダセーけど普通にifでもいける

.then(snapshot => {
      const data = snapshot.data();
      if(data !== undefined){
        response.send(data.city);
      }
      response.send(data);
    })

これでbashからshell叩いてエンドポイントを改めて見に行くと

tokyo

となっています。良いですね

localでの動作が確認できたのでデプロイします
どっちかのコマンドでいけます
僕は下じゃないとエラーになりますので...

firebase deploy
firebase deploy --project cloud-function-114514

まとめ: 他のAPI作成と比べて

  • 新規プロジェクトの作成のしやすさ
  • シンプルなモデル(Database)の作成
  • パスの設定
  • デプロイの手軽さ

で圧倒的に楽ですね
ただ大規模アプリには向いていない気もする
まぁ小出しに作ればええやろ?って思想なんだと思います

問題なのは料金と把握しきれるか(共通問題)ぐらいでしょうか
この機能だけcloud-functionで爆速実装なんてのは方針としては良さげですね