Cloud Functions for Firebaseを使用して、"最近の更新"の件数を制限する (STEP 3 : 他のユーザのタスクが見れるタスク管理アプリを作成する - React + Redux + Firebase チュートリアル)
★前回の記事
前回までで、/recentUpdatedTodosへのデータの追加を行うことはできましたが、これではどんどんデータが溜まって行ってしまうので、個数を制限します。制限を超えたら古いデータを削除します。
firebaseのサンプル(limit-children)があるので、このコードをもとにします。
実装方針
/recentUpdatedTodosに新しくデータが登録された時に、古いデータを削除します。何件のデータを残すかは、MAX_RECENT_UPDATED_TODOSで制御します。
動作確認を簡単にするため、MAX_RECENT_UPDATED_TODOSは一旦”3”にします。
“/recentUpdatedTodos”の子ノードの数の取得
はじめに、/recentUpdatedTodosの子ノードの数の取得をするコードを書きます。削除処理が必要なのは子の数がMAX_RECENT_UPDATED_TODOSより大きい場合なので、それ以下の場合は早期にreturnします。
functions/index.js
const MAX_RECENT_UPDATED_TODOS = 3; exports.limitRecentUpdatedTodos = functions.database.ref('/recentUpdatedTodos/{todoId}/_updatedAt') // #1 .onCreate((snapshot, context) => { const recentUpdatedTodosRef = snapshot.ref.parent.parent; // #2 return recentUpdatedTodosRef.once('value').then((todosSnapshot) => { // #3 console.log('numChildren: ' + todosSnapshot.numChildren()); // #4 if (todosSnapshot.numChildren() <= MAX_RECENT_UPDATED_TODOS) { console.log('Less than or equals to ' + MAX_RECENT_UPDATED_TODOS); return null; } console.log('More than ' + MAX_RECENT_UPDATED_TODOS); return null; }); })
- データ追加のトリガを
/recentUpdatedTodos/{todoId}/_updatedAtに設定します(#1)。 /recentUpdatedTodosは、_updatedAtから見て親の親なので、/recentUpdatedTodosのリファレンスはsnapshot.ref.parent.parentで取得することができます(#2)。/recentUpdatedTodosのデータを取得します(#3)。- 子ノードの個数は
numChildren()で取得します(#4)。
子ノード数取得の動作確認
デプロイして動作確認します。
$ cd todo-sample $ firebase deploy --only functions
動作確認のため、一旦DBの/recentUpdatedTodosの子ノードを削除します。

タスクを作成・更新して、/recentUpdatedTodosにデータを追加します。

Cloud Functionsのログを確認します。

/recentUpdatedTodos```の子ノードの数と、MAX_RECENT_UPDATED_TODOS``より大きいか小さいかが表示されました。
制限件数を超えたら、古いデータを削除する
制限件数を超えたら、古いデータから削除するように修正します。データを_updatedAtで並び替え、最初の方のデータから削除します。
functions/index.js
const MAX_RECENT_UPDATED_TODOS = 3; exports.limitRecentUpdatedTodos = functions.database.ref('/recentUpdatedTodos/{todoId}/_updatedAt') .onCreate((snapshot, context) => { const recentUpdatedTodosRef = snapshot.ref.parent.parent; return recentUpdatedTodosRef.orderByChild('_updatedAt').once('value').then((todosSnapshot) => { // #1 if (todosSnapshot.numChildren() <= MAX_RECENT_UPDATED_TODOS) { return null; } let childCount = 0; const updates = {}; todosSnapshot.forEach((child) => { // remove old updates if (++childCount <= todosSnapshot.numChildren() - MAX_RECENT_UPDATED_TODOS) { // #2 updates[child.key] = null; // #3 } }); return recentUpdatedTodosRef.update(updates); // #4 }); })
- 最近の更新のデータを最終更新時間順に並び変えるため、
orderByChild('_updatedAt’を追加します(#1)。データは昇順に並びます。 子ノードの個数 - MAX_RECENT_UPDATED_TODOSぶん、/recentUpdatedTodosの子ノードを削除します(#2)。- 削除したいデータの値を
nullにします(#3)。 - 更新内容を、
updateの引数として渡します(#4)。
件数の制限の動作確認
デプロイして動作確認します。
$ cd todo-sample $ firebase deploy --only functions
実行前の/recentUpdatedTodosです。

_updateAtの古い順に①②③④と番号を振りました。
タスクを1件追加します。

追加後の/recentUpdatedTodosです。

①と②のデータが消えて、件数が3件に制限されました。件数制限のスクリプトがうまく動いています。
保存件数の変更
今回は最新の10件をビューで表示するので、MAX_RECENT_UPDATED_TODOSの値を”10”に変更します。
const MAX_RECENT_UPDATED_TODOS = 10;
デプロイします。
$ cd todo-sample $ firebase deploy --only functions
以上で、Cloud Functions for Firebaseを使用して、"最近の更新"の件数を制限することができました。
★次回の記事
★目次