0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Firestoreの変更をCloudFunctionでTriggerする方法

Last updated at Posted at 2022-12-16

ConsoleUIで設定

この画像でTriggerの部分を見てもらうとCloudFirestoreとHTTPがあるのですが、これの設定方法について解説します。
Screenshot 2022-12-16 at 13.36.42.png

まず「CREATE FUNCTION」を押します。
次に、こういう感じの画面に変わります。
Screenshot 2022-12-16 at 13.39.54.png

1st or 2st gen の設定

Environmentは「1st gen」と「2st gen」があります。
2022年12月時点では、Firestoreのトリガーは1genでできるみたいでした。

Functionは、トップ画面で識別するための名前なので、「Function-1」とか適当にいれます。
Regionはサーバーの場所なのかな?Tokyoなので、asia-northeast1とかでいいと思います。

そのしたにTriggerってのがあって、ここがHTTPになっていますが、これを「CloudFirestore」に変えます。

そしたらこんな画面に変わります。
Screenshot 2022-12-16 at 13.44.15.png

EventTypeの設定

で、EventTypeを設定します。
Screenshot 2022-12-16 at 13.45.39.png

簡単にいうと、createが作成時にトリガー、updateが変更時にトリガー、deleteは削除時にトリガー、writeは作成か変更か削除でトリガーです。

Document Pathの設定

僕がハマったのは、この次のドキュメントPathの書き方です。公式のリファレンスでは、users/marieって書いたら、marieの変更が取れますって書いてるけど、僕がわからなかったのはusersはcollectionなのか、それとも予約語?みたいになりました。そこから色々試すことになりました。色々試してわかったのは、usersがcollection名で、marieはdocument名ってことでした。もし、「students」というcollectionと「bob」というdocument名があるならstudents/bobみたいな書き方になります。

Screenshot 2022-12-16 at 13.48.48.png

で、ネットで調べるとDocumentの内容の変更は取れるけど、collectionの変更は取れないみたいな記事があったような気がして、少し諦めていたのですが、全然問題なくcollectionにstudentsが追加されたら変更通知を受け取ることができました。

documentのbobが変更されたらトリガーされたい場合
students/bob

studentsに生徒が追加されたらトリガーされたい場合
students/{hoge}

(hogeのところはなんでもいいっぽいです)

最終的にこんな感じの書き方になります。
Screenshot 2022-12-16 at 14.05.09.png

これで、ConsoleUIからの設定方法は完了です。

コード

次にコードの部分です。
トリガーされたらこのメソッドが呼ばれます。呼び出すメソッド名はどこかで指定する場所がありました。そんなに迷うところでもないので、忘れました。

import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore
import json


def mendokusai(data, context):
    trigger_resource = context.resource

    print('Function triggered by change to: %s' % trigger_resource)

    print('\nOld value:')
    print(json.dumps(data["oldValue"]))

    print('\nNew value:')
    print(json.dumps(data["value"]))

    # FirestoreにPythonから追加する時のドキュメントとかに書いてるkeyです。
    key_path = "key.json"
    cred = credentials.Certificate(key_path)
    firebase_admin.initialize_app(cred)
    db = firestore.client()

    params = {}

    # dataは引数から入ってくるdictionaryなんですが、中身の例を載せておきます。
    # json.dumps(data["value"])で、中身をみたら大体わかると思います。

    fields = data["value"]["fields"]
    for key in fields.keys():
        for data_type, val in fields[key].items():
            if data_type == "integerValue":
                params[key] = int(val)
            elif data_type == "stringValue":
                params[key] = val
            else:
                raise f"[ERROR] Unxpected data type {data_type}"

    doc = db.collection(u'students').document(params["id"])
    doc.set(params)
    return 0

Shellからデプロイする方法

Shellから、デプロイする方法について書きます。
ConsoleUIからデプロイするなら不要です。

# documentPathの書き方 (document_wildcardの部分をトリガーしたい内容に置き換えます)
projects/my_project_id_11922960/databases/(default)/documents/collection/{document_wildcard}

例えば、collectionの「students」にdocumentが追加されたら通知を取りたい場合はこう書きます
projects/my_project_id_11922960/databases/(default)/documents/students/{student}
cd ~/MyProject/
gcloud functions deploy students_trigger \
  --entry-point mendokusai \  # メソッド名です
  --runtime python38 \
  --trigger-event "providers/cloud.firestore/eventTypes/document.write" \
  --trigger-resource "projects/surf-69998/databases/(default)/documents/students/{student}" \
  --region asia-northeast1 \
  --allow-unauthenticated

感想

なんか、英語で検索しても、いまいち情報が少なくて、結局自力で値をはめ込んで、動きを確認するのを繰り返したために時間がかかりました。
FirestoreとcloudFunctionについて詳しい人とか実際のプロジェクトで運用している知り合いを増やしたいです。なんかそういうコミュニティがあるのかな。。
シェルからデプロイする方が、テストしやすいのですが、コードを管理するのが面倒なので、CosoleUIのがいいのかな。
でもバックアップとして、残しておいた方がいいのかも。リポジトリ増えるの面倒なんだけどな。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?