CloudFirestoreにドキュメントが投稿されたら投稿数をインクリメントするCloudFunctionsを実装 #CloudFirestore #CloudFunctions

技術話

 

 

こんにちはフクシャチョーです。

Firebaseとお友達月間です。

今回の実装内容

さて、よくあるあるアプリの実装で、ユーザーが何らかのデータを投稿する、というのがあります。twitterとかInstagramとか・・・諸々のアプリでおなじみの操作です。

 

アプリからユーザーのアカウントページを見ると、そのユーザーの投稿数が表示されますよね。この投稿数をCloudFunctionsで集計します。

 

CloudFirestoreにあるコレクションは以下のような感じ

  • users ・・・ユーザーデータ
  • posts・・・投稿データ

アプリから投稿する際にはpostsコレクションにドキュメントが追加されます。

このドキュメントが追加されたイベントトリガーで、投稿したユーザーのpostCountsフィールドをインクリメントするCloudFunctionsを実装します。

 

プロジェクト設定

ログインしてプロジェクトの設定

この一連の操作は覚えておきましょう。

$firebase login

$firebase init functions

$firebase use --add

自分が利用するFirebaseのプロジェクトを設定しましょう

コード

今回はinitの時にTypeScriptを選択しました。

index.js

import * as collection from './collection';

export const updatePostCount = collection.updatePostCount;

collection.js

import * as functions from "firebase-functions";

import * as admin from "firebase-admin";
admin.initializeApp(functions.config().firebase);

export const updatePostCount = functions.firestore
    .document("posts/{postId}")
    .onCreate(async event => {
        // Get the post UserID
        const userId = event.data().userId;

        // Reference user doc
        const db = admin.firestore();
        const userRef = db.collection("users").doc(userId);

        // Get the user data
        const user = await userRef.get();

        // Update the count and run the update
        const postCount = (user.data().postCount || 0) + 1;

        return userRef.update({
            postCount
        });
    });

 

postsドキュメントがonCreateした時に実行します。

postドキュメントからuserIdを取得して、そのユーザーIDをもつユーザーのドキュメントのpostCount フィールドをインクリメントするようにしています。

 

イベントパラメーターとデータプロパティについて

Events and Triggers  |  Cloud Functions Documentation  |  Google Cloud 

PropertyDescriptionType
dataThe data object for the event.Object
contextThe context object for the event.Object
context.eventIdA unique ID for the event.String
context.timestampThe date/time this event was created.String (ISO 8601)
context.eventTypeThe type of the event.String
context.resourceThe resource that emitted the event.String

実際のデータは event.dataプロパティに含まれています。

イベントタイプによってデータは変わるので、以下を参照してください。

CloudStorageの場合、event.dataには、取得したデータのオブジェクトが返却されてきます。

なので、上記ではevent.data().userIdでユーザーIDを取得しています。

 

Cloud Firestoreのイベントについて

※ Cloud Firestore は、createupdatedeletewrite イベントをサポートしています。

イベントタイプトリガー
onCreateドキュメントが最初に書き込まれたときにトリガーされます。
onUpdateすでに存在するドキュメントの値が変更されたときにトリガーされます。
onDeleteデータを含むドキュメントが削除されたときにトリガーされます。
onWriteonCreateonUpdate または onDelete がトリガーされたときにトリガーされます。

 

デプロイ

$firebase  deploy --only functions

プログラムに異常がなくて、デプロイ時にエラーになる場合は懲りずに数回実行してみましょう。

 

 

アップされたことを確認したら、確認して実行しましょう。

 

実行

さて、ユーザーがpost ドキュメントを投稿する前に、現状どうなっているか確認してから投稿をしましょう。

投稿前のCloudStorageにあるusersドキュメント

ドキュメントのpostCountフィールドの値は0です。

ここで、postドキュメントを投稿してみましょう

 

 

投稿後のCloudStorageドキュメントにあるusersドキュメント

postドキュメントを投稿したあとは、postCountフィールドの値は1になっています。

もちろんpostコレクションのデータも1増えています。

 

 

Functionsのログを確認

Functionsのログを確認してみましょう。OKで終了していますね。

 

 

これで、ユーザーがドキュメントを投稿する都度、usersのpostCountがインクリメントされていきます。

削除がある場合は、その処理も追加しておきましょう。

 

 

集計の処理はCloudFunctionsに任せてしまうとアプリ側の処理は楽になりますね。

 

Enjoy!

タイトルとURLをコピーしました