Cloud Functions for Firebaseを使用して、タスク作成時に"最近の更新"へデータを追加する (STEP 3 : 他のユーザのタスクが見れるタスク管理アプリを作成する - React + Redux + Firebase チュートリアル)

★前回の記事

yucatio.hatenablog.com

addRecentUpdateOnCreateを実装します。タスクが作成された時に、/recentUpdatedTodosにデータを追加します。

表示したいデータ

“最近の更新”は、以下のようになります。ユーザ名をクリックすると、ユーザのタスク一覧へ遷移します。

f:id:yucatio:20181011124946p:plain

これを表示するのに以下のデータが必要になります。

  • uid (ユーザID)
  • displayName (ユーザ名)
  • todo.text (タスク名)
  • 作成か更新か
  • 更新時間

/recentUpdatedTodosの下にtodoIdをキーとしてデータを作成するので、

  • todoId

のデータも必要です。/recentUpdatedTodosの下にtodoIdをキーとしてデータを作成することによって、1つのタスクが短時間に何度も更新されても、画面への表示は最後の1回だけになります。また、べき等性も担保されます。

必要なデータについては、

  • uidとtodoIdについてはパスパラメータの値を使用します。
  • displayNameは/users/{uid}/displayNameから取得します。
  • todo.textは作成についてはそのまま値を取得することができますが、更新の場合は一旦親ノードを取得してからtextの値を取得する必要があります。
  • 作成か更新かについては、eventTypeというプロパティを用意し、CREATEまたはUPDATEをセットするようにします。
  • 更新時間はadmin.database.ServerValue.TIMESTAMPで取得します。

タスク作成時に"最近の更新"へデータを追加する(displayName以外)

最初に、displayName以外の、

  • uid
  • todo.text
  • 作成か更新か
  • 更新時間

をtodoIdをキーとして/recentUpdatedTodosに登録します。

functions/index.js

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

    return admin.database().ref('/recentUpdatedTodos/' + todoId).set({  // #2
      uid,
      text,
      eventType: 'CREATE',
      _updatedAt: admin.database.ServerValue.TIMESTAMP
    });
})
  • 指定したpathの値は、snapshot.val()で取得できます(#1)。
  • /recentUpdatedTodos/{todoId}にデータをセットします(#2)。

動作確認(displayName以外)

デプロイします。

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

タスクを追加します。

f:id:yucatio:20181024112600p:plain:w200

データベースのデータを確認します。

f:id:yucatio:20181024113107p:plain

/recentUpdatedTodosにtodoIdをキーとして、uidとtext、eventType('CREATE')、更新時間(_updatedAt)が追加されました。

データが追加されない場合は、 Firebase console > Functions > ログで何かエラーが出ていないか確認してください。

タスク作成時に"最近の更新"へデータを追加する(displayNameを含める)

displayNameを追加します。displayNameは、/users/{uid}/displayNameで取得します。取得処理は非同期になります。

functions/index.js

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

    return admin.database().ref('/users/' + uid + '/displayName').once('value').then((snapshot) => {  // #1
      const displayName = snapshot.val();
      return admin.database().ref('/recentUpdatedTodos/' + todoId).set({
        uid,
        displayName,
        text,
        eventType: 'CREATE',
        _updatedAt: admin.database.ServerValue.TIMESTAMP
      });
    });
})
  • /users/{uid}/displayNameonce()で取得します(#1)。

動作確認(displayNameを含める)

デプロイして動作確認します。

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

タスクを追加します。

f:id:yucatio:20181024115013p:plain:w200

データベースのデータを確認します。

f:id:yucatio:20181024115550p:plain /recentUpdatedTodosにtodoIdをキーとして、uidとdisplayName、text、eventType('CREATE')、更新時間(_updatedAt)が追加されました。

以上でタスク作成時に"最近の更新"へデータを追加することができました。

★次回の記事

yucatio.hatenablog.com

★目次

yucatio.hatenablog.com