yucatio@システムエンジニア

趣味で作ったものいろいろ

Cloud Functions for Firebase用の最初のコードの記述とデプロイ (STEP 3 : 他のユーザのタスクが見れるタスク管理アプリを作成する - React + Redux + Firebase チュートリアル)

★前回の記事

yucatio.hatenablog.com

Cloud Functions for Firebaseで最初に小さいコードを書いて動作確認をします。 手始めに、DBの/todos/{uid}の下にタスクが追加された時と、タスクが更新された時にコンソールへメッセージを表示します。

トリガの動作確認用コードの作成

/todos/{uid}/の下にタスクが追加された時と、タスクが更新された時にコンソールにメッセージを表示します。

functions/index.js

const functions = require('firebase-functions');  // #1
const admin = require('firebase-admin');  // #2
admin.initializeApp();  // #3

exports.addRecentUpdateOnCreate = functions.database.ref('/todos/{uid}/{todoId}/text')  // #4
  .onCreate((snapshot, context) => {
    const uid = context.params.uid;  // #5
    const todoId = context.params.todoId;  // #6

    console.log('addRecentUpdateOnCreate called. uid=' + uid + ', todoId=' + todoId);  // #7

    return null;  // #8
})

exports.addRecentUpdateOnUpdateCompleted = functions.database.ref('/todos/{uid}/{todoId}/completed')  // #9
  .onUpdate((change, context) => {
    const todoId = context.params.todoId;
    const uid = context.params.uid;

    console.log('addRecentUpdateOnUpdateCompleted called. uid=' + uid + ', todoId=' + todoId);

    return null;
})
  • firebase-functionsを使用します(#1)。このモジュールはCloud Functionを使用するのに必要です。
  • firebase-adminを使用します(#2)。このモジュールはFirebase Realtime Databaseを利用するのに必要です。
  • admin.initializeAppでadminを初期化します(#3)。
  • タスクが追加された時に実行される関数を定義します(#4)。functions.database.ref('/todos/{uid}/{todoId}/text’).onCreate()/todos/{uid}/{todoId}/text’が新規作成された時に、onCreateの引数で与えた関数を実行します。パスは、/todos/{uid}/{todoId}でなく、/todos/{uid}/{todoId}/textです。なるべく深い所にトリガを設定します。
  • pathで波括弧で囲った部分はパラメータとして扱われ、context.params.{パラメータ名}で取得することができます(#5, #6)。
  • console.logで、Firebaseのコンソールにログを出力することが可能になります(#7)。
  • 関数はPromiseか値を返す必要があります。特に返す値がない場合はnullでよいでしょう(#8)。処理が完了した時に何も返さないとエラーになります。
  • タスクが更新された時に実行される関数を定義します(#9)。今回はcompletedの値しか変化しないので、pathは/todos/{uid}/{todoId}/completedです。

Cloud Functionsのデプロイ

functions/index.jsをデプロイします。

$ cd todo-sample
$ firebase deploy --only functions

=== Deploying to 'todo-sample-xxxxx’…

i  deploying functions
Running command: npm --prefix "$RESOURCE_DIR" run lint

> functions@ lint /Users/yuka/react/todo-sample/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 (55.94 KB) for uploading
✔  functions: functions folder uploaded successfully
i  functions: creating Node.js 6 function addRecentUpdateOnCreate(us-central1)...
i  functions: creating Node.js 6 function exports.addRecentUpdateOnUpdateCompleted(us-central1)...
✔  functions[addRecentUpdateOnCreate(us-central1)]: Successful create operation. 
✔  functions[exports.addRecentUpdateOnUpdateCompleted(us-central1)]: Successful create operation. 

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/todo-sample-xxxxx/overview

デプロイが完了しました。

Firebaseコンソールでデプロイした関数を確認します。

f:id:yucatio:20181023132227p:plain

動作確認

タスクを追加します。

f:id:yucatio:20181023132805p:plain:w200

コンソールを確認します。

f:id:yucatio:20181023133600p:plain

addRecentUpdateOnCreate called.と、uidとtodoIdが表示されていることが確認できました。

タスクを更新します。

f:id:yucatio:20181023134415p:plain:w200

コンソールを確認します。

f:id:yucatio:20181023133909p:plain

addRecentUpdateOnUpdateCompleted called.と、uidとtodoIdが表示されていることが確認できました。

以上で、/todos/{uid}の下にタスクが追加された時と、タスクが更新された時にコンソールへメッセージを表示することができました。

作成トリガと更新トリガは、更新日時を使用するのがおすすめ

今回は、タスクの作成トリガは/todos/{uid}/{todoId}/textの作成、更新トリガは/todos/{uid}/{todoId}/completedの更新としました。問題なく動きますが、将来的に項目が増えた時にトリガを追加し忘れる恐れがあります。 また、データごとにトリガになるプロパティが違うのは面倒です。

この問題を解決するには、すべてのデータに、作成日付を表す_createdAtプロパティと更新日付を表す_updatedAtプロパティを付与します。データの作成は、_cretedAtの作成をトリガにし、データの更新は、_updatedAtの更新をトリガにします。

以下の記事でこれの対応をしています。

yucatio.hatenablog.com

★次回の記事

yucatio.hatenablog.com

★目次

yucatio.hatenablog.com