Cloud Run 関数と Eventarc を使用すると、Datastore モードの Firestore データベースの変更によってトリガーされるイベントを処理するコードをデプロイできます。これにより、独自のサーバーを実行しなくても、サーバー側の機能を追加できます。
Datastore モードのトリガー
Eventarc は、Datastore モードの Firestore イベント トリガーをサポートしています。これにより、Datastore モードの Firestore イベントに関連付けられた Cloud Run 関数(第 2 世代)ハンドラを作成できます。
イベントタイプ | トリガー |
---|---|
google.cloud.datastore.entity.v1.created |
エンティティが初めて書き込まれたときにトリガーされます。 |
google.cloud.datastore.entity.v1.updated |
エンティティがすでに存在し、値が変更されたときにトリガーされます。 |
google.cloud.datastore.entity.v1.deleted |
エンティティが削除されるとトリガーされます。 |
google.cloud.datastore.entity.v1.written |
created 、updated または deleted がトリガーされたときにトリガーされます。 |
google.cloud.datastore.entity.v1.created.withAuthContext |
created と同じですが、認証情報を追加します。 |
google.cloud.datastore.entity.v1.updated.withAuthContext |
updated と同じですが、認証情報を追加します。 |
google.cloud.datastore.entity.v1.deleted.withAuthContext |
deleted と同じですが、認証情報を追加します。 |
google.cloud.datastore.entity.v1.written.withAuthContext |
written と同じですが、認証情報を追加します。 |
Datastore モードのイベント トリガーはエンティティの変更にのみ応答します。Datastore モード エンティティの更新でデータが変更されない場合(オペレーションなしの書き込み)、更新イベントや書き込みイベントは生成されません。特定のプロパティに対してのみイベントを生成することはできません。
イベントに認証コンテキストを含める
イベントに関する追加の認証情報を含めるには、withAuthContext
拡張機能とともにイベント トリガーを使用します。この拡張機能は、イベントをトリガーしたプリンシパルに関する追加情報を追加します。ベースイベントで返される情報に加えて、authtype
属性と authid
属性を追加します。属性値の詳細については、authcontext
のリファレンスをご覧ください。
エンティティでトリガーされる関数を作成する
Datastore モードの Firestore のイベントに応答する関数を作成するには、デプロイ中に次の内容を指定する準備を行います。
- トリガー イベントのタイプ
- 関数に関連付けられたエンティティを選択するトリガー イベント フィルタ
- 実行する関数コード
トリガー イベント フィルタ
イベント フィルタを指定するときに、エンティティの完全一致またはパスパターンを指定できます。パスパターンを使用して、ワイルドカード *
または **
を使用して複数のエンティティに一致させます。
たとえば、完全一致を指定して、次のエンティティの変更に応答できます。
users/marie
パターンに一致するエンティティの変更に対応するには、ワイルドカード *
または **
を使用します。*
ワイルドカードは単一のセグメントに一致し、**
マルチセグメント ワイルドカードはパターン内の 0 個以上のセグメントに一致します。
単一セグメントの一致(*
)の場合は、users/{userId}
などの名前付きキャプチャ グループを使用することもできます。
次の表に、有効なパスパターンを示します。
パターン | 説明 |
---|---|
users/* または users/{userId} |
種類 users のすべてのエンティティを照合します。/users/marie/messages/33e2IxYBD9enzS50SJ68 のような子孫エンティティ レベルは照合しません。 |
users/** |
種類 users のすべてのエンティティと、/users/marie/messages/33e2IxYBD9enzS50SJ68 などのすべての子孫エンティティに一致します。 |
パスパターンの詳細については、Eventarc パスのパターンをご覧ください。
ワイルドカードを使用する場合でも、トリガーは常にエンティティを指している必要があります。次の例をご覧ください。
{messages=*}
は種類 ID であるため、users/{userId=*}/{messages=*}
は無効です。{messageId=*}
は常にエンティティを指すため、users/{userId=*}/{messages}/{messageId=*}
は有効です。
文字のエスケープ処理
このセクションでは、種類 ID とエンティティ ID の文字をエスケープする必要がある状況について説明します。文字をエスケープすると、イベント フィルタは ID を正しく解釈できます。
種類 ID またはエンティティ ID に
~
または/
の文字が含まれている場合は、イベント フィルタで ID をエスケープする必要があります。ID をエスケープするには、__escENCODED_ID__
の形式を使用します。ENCODED_ID は、すべての~
と/
の文字をエンコード ID に置き換えた種類 ID またはエンティティ ID に置き換えます。次に例を示します。~
:~0
/
:~1
たとえば、種類 ID
user/profile
は__escusers~1profile__
になります。この種類 ID を持つパスパターンの例は__escusers~1profile__/{userId}
です。イベント フィルタで
.
または..
の種類 ID またはエンティティ ID を使用する場合は、次のように ID をエスケープする必要があります。.
:__esc~2__
..
:__esc~2~2__
.
文字をエスケープする必要があるのは、ID が.
または..
の場合のみです。たとえば、種類 IDcustomers.info
ではエスケープは必要ありません。種類またはエンティティ ID が文字列値ではなく数値の場合は、
__idNUMERIC_VALUE__
で ID をエスケープする必要があります。たとえば、種類が111
でエンティティ ID が222
のエンティティのパスパターンは__id111__/__id222__
です。以前の Cloud Datastore から Datastore モードの Firestore に移行した場合、データベースに UTF8 以外のエンコードの以前の ID が含まれている可能性があります。これらの ID は、
__bytesBASE64_ENCODING__
でエスケープする必要があります。BASE64_ENCODING は、ID の Base64 エンコードに置き換えます。たとえば、UTF8 以外の種類 IDTask
のエスケープを含むパスパターンTask/{task}
は、__bytesVGFzaw==__/{task}
になります。
関数の例
次の例では、Datastore モードのイベントを受信する方法を示しています。イベントに関連するデータを操作するには、value
フィールドと old_value
フィールドを確認します。
value
: オペレーション後のエンティティ スナップショットを含むEntityResult
オブジェクト。このフィールドは、削除イベントについては入力されません。old_value
: オペレーション前のエンティティ スナップショットを含むEntityResult
オブジェクト。このフィールドは、更新イベントと削除イベントに対してのみ入力されます。
Java
Datastore モードのクライアント ライブラリをインストールして使用する方法については、Datastore モードのクライアント ライブラリをご覧ください。 詳細については、Datastore モードの Java API のリファレンス ドキュメントをご覧ください。
Datastore モードへの認証を行うには、アプリケーションのデフォルト認証情報を設定します。 詳細については、ローカル開発環境の認証を設定するをご覧ください。
proto 依存関係をソースに含める
関数のソース ディレクトリに Datastore モード data.proto
ファイルを含める必要があります。このファイルは、ソース ディレクトリにも含める必要がある次の proto をインポートします。
依存関係に同じディレクトリ構造を使用します。たとえば、struct.proto
は google/protobuf
内に配置します。
これらのファイルは、イベントデータをデコードするのに必要です。関数のソースにこれらのファイルが含まれていない場合は、実行時にエラーが返されます。
イベント属性
各イベントには、イベントがトリガーされた時間など、イベントに関する情報を含むデータ属性が含まれます。Datastore モードの Firestore は、イベントに関連するデータベースとエンティティに関するデータを追加します。これらの属性には、次のようにアクセスできます。
Java
logger.info("Event time " + event.getTime()); logger.info("Event project: " + event.getExtension("project")); logger.info("Event location: " + event.getExtension("location")); logger.info("Database name: " + event.getExtension("database")); logger.info("Database namespace: " + event.getExtension("namespace")); logger.info("Database entity: " + event.getExtension("entity")); // For withAuthContext events logger.info("Auth information: " + event.getExtension("authid")); logger.info("Auth information: " + event.getExtension("authtype"));
関数をデプロイする
Cloud Run 関数をデプロイするユーザーには、Cloud Run 関数デベロッパーの IAM ロールまたは同等の権限を含むロールが必要です。デプロイの追加構成もご覧ください。
関数をデプロイするには、gcloud CLI または Google Cloud コンソールを使用します。以下の例は、gcloud CLI を使用したデプロイを示しています。Google Cloud コンソールを使用したデプロイの詳細については、Cloud Run 関数をデプロイするをご覧ください。
-
In the Google Cloud console, activate Cloud Shell.
At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
gcloud functions deploy
コマンドを使用して、関数をデプロイします。gcloud functions deploy FUNCTION_NAME \ --gen2 \ --region=FUNCTION_LOCATION \ --trigger-location=TRIGGER_LOCATION \ --runtime=RUNTIME \ --source=SOURCE_LOCATION \ --entry-point=CODE_ENTRYPOINT \ --trigger-event-filters="type=EVENT_FILTER_TYPE" \ --trigger-event-filters="database=DATABASE" \ --trigger-event-filters="namespace=NAMESPACE" \ --trigger-event-filters-path-pattern="entity=ENTITY_OR_PATH" \
最初の引数 FUNCTION_NAME は、デプロイされた関数の名前です。関数名は、先頭を文字にし、その後に 62 文字以下の文字、数字、ハイフン、アンダースコアを続けます。末尾は文字または数字にする必要があります。FUNCTION_NAME は、有効な関数名に置き換えます。さらに、次のフラグを追加します。
--gen2
フラグは、Cloud Run 関数(第 2 世代)にデプロイすることを指定します。このフラグを省略すると、Cloud Run 関数(第 1 世代)にデプロイされます。--region=FUNCTION_LOCATION
フラグには、関数をデプロイするリージョンを指定します。近接性を最大化するには、Firestore データベースの近くのリージョンに FUNCTION_LOCATION を設定します。Firestore データベースがマルチリージョン ロケーションにある場合、
nam5
のデータベースの場合はus-central1
に、eur3
のデータベースの場合はeurope-west4
に値を設定します。リージョン Firestore のロケーションの場合は、同じリージョンに設定します。--trigger-location=TRIGGER_LOCATION
フラグには、トリガーのロケーションを指定します。 TRIGGER_LOCATION は、Datastore モード データベースのロケーションに設定する必要があります。--runtime=RUNTIME
フラグには、関数で使用される言語ランタイムを指定します。Cloud Run 関数は複数のランタイムをサポートしています。詳細については、ランタイムをご覧ください。RUNTIME をサポートされているランタイムに設定します。--source=SOURCE_LOCATION
フラグには、関数のソースコードの場所を指定します。詳細については、以下をご覧ください。SOURCE_LOCATION を関数のソースコードの場所に設定します。
--entry-point=CODE_ENTRYPOINT
フラグには、ソースコード内の関数のエントリ ポイントを指定します。これは、関数の実行時に実行されるコードです。CODE_ENTRYPOINT は、ソースコード内に存在する関数名または完全修飾クラス名に設定する必要があります。詳細については、関数のエントリ ポイントをご覧ください。--trigger-event-filters
フラグは、トリガーのタイプとイベントをトリガーするエンティティまたはパスを含むイベント フィルタを定義します。次の属性値を設定して、イベントフィルタを定義します。type=EVENT_FILTER_TYPE
: Firestore は、次のイベントタイプをサポートしています。google.cloud.datastore.entity.v1.created
: エンティティが初めて書き込まれたときにイベントが送信されます。google.cloud.datastore.entity.v1.updated
: エンティティがすでに存在し、値が変更されたときにイベントが送信されます。google.cloud.datastore.entity.v1.deleted
: エンティティが削除されたときにイベントが送信されます。google.cloud.datastore.entity.v1.written
: エンティティが作成、更新、削除されたときにイベントが送信されます。google.cloud.datastore.entity.v1.created.withAuthContext
: ドキュメントが最初に書き込まれたときにイベントが送信されます。このイベントには追加の認証情報が含まれています。google.cloud.datastore.entity.v1.updated.withAuthContext
: ドキュメントがすでに存在し、値が変更されたときに、イベントが送信されます。追加の認証情報が含まれますgoogle.cloud.datastore.entity.v1.deleted.withAuthContext
: ドキュメントが削除されたときにイベントが送信されます。追加の認証情報が含まれますgoogle.cloud.datastore.entity.v1.written.withAuthContext
: ドキュメントが作成、更新、または削除されたときにイベントが送信されます。追加の認証情報が含まれます
EVENT_FILTER_TYPE は、次のいずれかのイベントタイプに設定します。
database=DATABASE
: Firestore データベース。デフォルトのデータベース名には、DATABASE を(default)
に設定します。namespace=NAMESPACE
: データベースの名前空間。デフォルトのデータベース名には、NAMESPACE を(default)
に設定します。名前空間に合わせてフラグを削除します。entity=ENTITY_OR_PATH
: データが作成、更新、削除されたときにイベントをトリガーするデータベース パス。ENTITY_OR_PATH に指定できる値は以下のとおりです。- 等しい。例:
--trigger-event-filters="entity='users/marie'"
- 経路パターン。例:
--trigger-event-filters-path-pattern="entity='users/*'"
詳細については、パスパターンについてをご覧ください。
- 等しい。例:
関数をデプロイするときに、追加の構成、ネットワーキング、セキュリティのオプションを指定することもできます。
デプロイ コマンドとそのフラグの詳細については、
gcloud functions deploy
のドキュメントをご覧ください。
デプロイの例
次の例は、Google Cloud CLI を使用したデプロイを示しています。
us-west2
リージョンにデータベースの関数をデプロイします。
gcloud functions deploy gcfv2-trigger-datastore-node \
--gen2 \
--region=us-west2 \
--trigger-location=us-west2 \
--runtime=nodejs18 \
--source=gs://example_bucket-1/datastoreEventFunction.zip \
--entry-point=makeUpperCase \
--trigger-event-filters=type=google.cloud.datastore.entity.v1.written \
--trigger-event-filters=database='(default)' \
--trigger-event-filters-path-pattern="entity='messages/{pushId}'"
nam5
マルチリージョンにデータベースの関数をデプロイします。
gcloud functions deploy gcfv2-trigger-datastore-python \
--gen2 \
--region=us-central1 \
--trigger-location=nam5 \
--runtime=python311 \
--source=gs://example_bucket-1/datastoreEventFunction.zip \
--entry-point=make_upper_case \
--trigger-event-filters=type=google.cloud.datastore.entity.v1.written.withAuthContext \
--trigger-event-filters=database='(default)' \
--trigger-event-filters-path-pattern="entity='messages/{pushId}'"
制限事項
Cloud Run 関数の Firestore トリガーには、次の制限事項があります。
- Cloud Run 関数(第 1 世代)では、Firestore ネイティブ モードの既存の「(default)」データベースがあることが前提となります。Firestore の名前付きデータベースや Datastore モードはサポートされていません。これらを使用している場合にイベントを構成するには、Cloud Run 関数(第 2 世代)を使用してください。
- 順序は保証されません。短時間に複数の変更を行うと、予期しない順序で関数の呼び出しがトリガーされることがあります。
- イベントは必ず 1 回以上処理されますが、1 つのイベントで関数が複数回呼び出される場合があります。「正確に 1 回」のメカニズムに依存することは避け、べき等性がある関数を記述してください。
- Datastore モードの Firestore には、Cloud Run 関数(第 2 世代)が必要です。Cloud Run 関数(第 1 世代)では、Datastore モードはサポートされていません。
- トリガーは、単一のデータベースに関連付けられます。複数のデータベースに一致するトリガーは作成できません。
- データベースを削除しても、そのデータベースのトリガーは自動的に削除されません。トリガーはイベントの配信を停止しますが、トリガーを削除するまで存在し続けます。
- 一致したイベントが最大リクエスト サイズを超えると、Cloud Run functions(第 1 世代)に配信されない可能性があります。
- リクエスト サイズが原因で配信されなかったイベントは、プラットフォーム ログに記録され、プロジェクトのログ使用量にカウントされます。
- これらのログは、ログ エクスプローラで「サイズが第 1 世代の上限を超えているため、イベントを Cloud Functions に配信できません...」という
error
重大度メッセージとともに表示されます。関数名はfunctionName
フィールドで確認できます。receiveTimestamp
フィールドが現在から 1 時間以内であれば、タイムスタンプの前後のスナップショットで問題のドキュメントを読み取ることで、実際のイベントの内容を推測できます。 - このようなケイデンスを回避するには、次のようにします。
- Cloud Run 関数(第 2 世代)に移行してアップグレードする
- ドキュメントのサイズを縮小する
- 問題の Cloud Run 関数を削除する
- 除外を使用してロギング自体を無効にすることもできますが、問題のあるイベントは引き続き配信されないことに注意してください。
Eventarc と Datastore モードの Firestore のロケーション
Eventarc は、Firestore イベント トリガーのマルチリージョンをサポートしていませんが、マルチリージョン ロケーションの Firestore データベースのトリガーは作成できます。Eventarc は、Firestore マルチリージョン ロケーションを次の Eventarc リージョンにマッピングします。
Firestore マルチリージョン | Eventarc リージョン |
---|---|
nam5 |
us-central1 |
eur3 |
europe-west4 |
次のステップ
- イベント ドリブン アーキテクチャについて確認する。
- Datastore モードのコードサンプルを確認する。