Cloud Functions for Firebase を使用すると、Firebase Data Connect 内のイベントを処理できます。Cloud Functions を使用すると、Data Connect サービスでのミューテーションの実行などのイベントに応じてサーバーサイド コードを実行できます。これにより、独自のサーバーをデプロイせずにカスタム ロジックを追加できます。
一般的なユースケース
データ同期: 変更が発生した後、他のシステム(Cloud Firestore、BigQuery、外部 API など)とデータを複製または同期します。
非同期ワークフロー: データベースの変更後に、画像処理やデータ集計などの長時間実行されるプロセスを開始します。
ユーザー エンゲージメント: アカウントの作成など、アプリケーション内の特定のミューテーション イベントの後に、ユーザーにメールまたは Cloud Messaging 通知を送信します。
Data Connect ミューテーションで関数をトリガーする
onMutationExecuted イベント ハンドラを使用して、Data Connect ミューテーションが実行されるたびに関数をトリガーできます。このトリガーは、ミューテーションの実行時に発生します。
基本的なミューテーション イベント関数
次の基本的な例は、Data Connect サービスで実行されたミューテーションの詳細をログに記録する関数です。
Node.js
import { onMutationExecuted } from "firebase-functions/dataconnect";
import { logger } from "firebase-functions";
export const logMutation = onMutationExecuted(
{
/* Trigger on all mutations, spanning all services and connectors
in us-central1 */
},
(event) => {
logger.info("A mutation was executed!", {
data: event.data,
});
}
);
Python
from firebase_functions import dataconnect_fn, logger
@dataconnect_fn.on_mutation_executed()
def log_mutation(event: dataconnect_fn.Event):
logger.info("A mutation was executed!", event.data)
プロジェクト内のすべてのミューテーションをトリガーする場合は、トリガー ハンドラでミューテーションを実行しないでください。無限ループが発生します。イベント トリガーでミューテーションを実行する場合は、以下で説明するフィルタリング オプションを使用し、ミューテーションがそれ自体をトリガーしないように注意してください。
関数のロケーションを設定する
イベントで関数をトリガーするには、関数のロケーションが Data Connect サービスのロケーションと一致している必要があります。デフォルトでは、関数リージョンは us-central1 です。
Node.js
import { onMutationExecuted } from "firebase-functions/dataconnect";
export const onMutationRegionOption = onMutationExecuted(
{
region: "europe-west1" // Set if Data Connect service location is not us-central1
},
(event) => { /* ... */ }
);
Python
@dataconnect_fn.on_mutation_executed(
region="europe-west1" # Set if Data Connect service location is not us-central1
)
def mutation_executed_handler_region_option(event: dataconnect_fn.Event):
pass
イベントをフィルタ
onMutationExecuted ハンドラは、特定の属性に基づいてイベントをフィルタするオプションで構成できます。これは、特定のミューテーションに対してのみ関数をトリガーする場合に便利です。
service、connector、operation でフィルタできます。
Node.js
import { onMutationExecuted } from "firebase-functions/dataconnect";
import { logger } from "firebase-functions";
// Trigger this function only for the CreateUser mutation
// in the users connector of the myAppService service.
export const onUserCreate = onMutationExecuted(
{
service: "myAppService",
connector: "users",
operation: "CreateUser",
},
(event) => {
logger.info("A new user was created!", event.data);
// Add logic here: for example, sending a welcome email.
}
);
Python
from firebase_functions import dataconnect_fn, logger
@dataconnect_fn.on_mutation_executed(
service="myAppService",
connector="users",
operation="CreateUser"
):
def on_user_create(event: dataconnect_fn.Event):
logger.info("A new user was created!", event.data)
ワイルドカードとキャプチャ グループ
ワイルドカードとキャプチャ グループを使用して、複数の値でトリガーをフィルタできます。キャプチャされたグループは event.params で使用できます。詳細については、パスパターンについてをご覧ください。
例:
Node.js
import { onMutationExecuted } from "firebase-functions/dataconnect";
// Trigger on all operations that match the pattern `User*`, on any service and
// connector.
export const onMutationWildcards = onMutationExecuted(
{
operation: "User*",
},
(event) => {}
);
// Trigger on all operations that match the pattern `User*`, on any service and
// connector. Capture the operation name in the variable `op`.
export const onMutationCaptureWildcards = onMutationExecuted(
{
operation: "{op=User*}",
},
(event) => {
// `event.params.op` contains the operation name.
}
);
// Trigger on all operations on the service `myAppService`. Capture the
// operation name in the variable `operation`.
export const onMutationCaptures = onMutationExecuted(
{
service: "myAppService",
operation: "{operation}",
},
(event) => {
// `event.params.operation` contains the operation name.
}
);
Python
from firebase_functions import dataconnect_fn
# Trigger on all operations that match the pattern `User*`, on any service and
# connector.
@dataconnect_fn.on_mutation_executed(
operation="User*"
)
def on_mutation_wildcards(event: dataconnect_fn.Event):
pass
# Trigger on all operations that match the pattern `User*`, on any service and
# connector. Capture the operation name in the variable `op`.
@dataconnect_fn.on_mutation_executed(
operation="{op=User*}"
)
def on_mutation_capture_wildcards(event: dataconnect_fn.Event):
# `event.params["op"]` contains the operation name.
pass
# Trigger on all operations on the service `myAppService`. Capture the
# operation name in the variable `operation`.
@dataconnect_fn.on_mutation_executed(
service="myAppService",
operation="{operation}"
)
def on_mutation_captures(event: dataconnect_fn.Event):
# `event.params["operation"]` contains the operation name.
pass
ユーザー認証情報にアクセスする
イベントをトリガーしたプリンシパルに関するユーザー認証情報にアクセスできます。認証コンテキストで使用可能なデータの詳細については、認証コンテキストをご覧ください。
次の例は、認証情報を取得する方法を示しています。
Node.js
import { onMutationExecuted } from "firebase-functions/dataconnect";
export const onMutation = onMutationExecuted(
{ operation: "MyMutation" },
(event) => {
// mutationExecuted event provides authType and authId:
// event.authType
// event.authId
}
);
Python
from firebase_functions import dataconnect_fn
@dataconnect_fn.on_mutation_executed(operation="MyMutation")
def mutation_executed_handler(event: dataconnect_fn.Event):
# mutationExecuted event provides auth_type and auth_id, which are accessed as follows
# event.auth_type
# event.auth_id
pass
認証タイプと認証 ID は次のように入力されます。
| Mutation initiated by | authtype | authid |
|---|---|---|
| 認証済みエンドユーザー | app_user |
Firebase Auth トークンの UID |
| 未認証のエンドユーザー | unauthenticated |
指定なし |
| エンドユーザーを装う Admin SDK | app_user
|
権限を借用したユーザーの Firebase Auth トークン UID |
| 認証されていないリクエストを装う Admin SDK | unauthenticated |
指定なし |
| 完全な権限を持つ Admin SDK | admin |
指定なし |
イベントデータにアクセスする
関数に渡される CloudEvent オブジェクトには、関数をトリガーしたイベントに関する情報が含まれています。
イベント属性
| 属性 | 型 | 説明 |
|---|---|---|
id |
string |
イベントの一意の識別子。 |
source
|
string
|
イベントを生成したコネクタ リソース(//firebasedataconnect.googleapis.com/projects/*/locations/*/services/*/connectors/* など)。 |
specversion |
string |
CloudEvents 仕様のバージョン(例: "1.0")。 |
type |
string |
イベントのタイプ: google.firebase.dataconnect.connector.v1.mutationExecuted。 |
time |
string |
イベントが生成されたときのタイムスタンプ(ISO 8601 形式)。 |
subject |
string |
省略可。オペレーション名など、イベント コンテキストに関する追加情報。 |
params |
object |
キャプチャされたパスパターンのマップ。 |
authType |
string |
イベントをトリガーしたプリンシパルのタイプを表す列挙型。 |
authId |
string |
イベントをトリガーしたプリンシパルの一意の識別子。 |
data |
MutationEventData |
Data Connect イベントのペイロード。次のセクションをご覧ください。 |
データ ペイロード
MutationEventData オブジェクトには、Data Connect イベントのペイロードが含まれます。
{
// ...
"authType": // ...
"data": {
"payload": {
"variables": {
"userId": "user123",
"updateData": {
"displayName": "New Name"
}
},
"data": {
"updateUser": {
"id": "user123",
"displayName": "New Name",
"email": "user@example.com"
}
},
"errors": []
}
}
}
payload.variables: ミューテーションに渡された変数を含むオブジェクト。payload.data: ミューテーションによって返されたデータを含むオブジェクト。payload.errors: ミューテーションの実行中に発生したエラーの配列。ミューテーションが成功した場合、この配列は空になります。
例
ミューテーション変数と返されたデータにアクセスする方法は次のとおりです。
Node.js
import { onMutationExecuted } from "firebase-functions/dataconnect";
import { logger } from "firebase-functions";
export const processNewUserData = onMutationExecuted(
{
"service": "myAppService",
"connector": "users",
"operation": "CreateUser",
},
(event) => {
// The variables passed to the mutation
const mutationVariables = event.data.payload.variables;
// The data returned by the mutation
const returnedData = event.data.payload.data;
logger.info("Processing mutation with variables:", mutationVariables);
logger.info("Mutation returned:", returnedData);
// ... your custom logic here
}
);
Python
from firebase_functions import dataconnect_fn, logger
@dataconnect_fn.on_mutation_executed(
service="myAppService",
connector="users",
operation="CreateUser"
):
def process_new_user_data(event: dataconnect_fn.Event):
# The variables passed to the mutation
mutation_vars = event.data.payload.variables
# The data returned by the mutation
returned_data = event.data.payload.data
logger.info("Processing mutation with variables:", mutationVariables)
logger.info("Mutation returned", returnedData)
# ... your custom logic here
Cloud Firestore や Realtime Database などの他のデータベース トリガーとは異なり、Data Connect イベントではデータの「前」のスナップショットは提供されません。Data Connect は基盤となるデータベースにリクエストをプロキシするため、データの「前」のスナップショットをトランザクション的に取得することはできません。代わりに、ミューテーションに送信された引数と、ミューテーションから返されたデータにアクセスできます。
このため、イベント トリガーが同じイベントをトリガーする無限ループを回避するために、「前」と「後」のスナップショットを比較する戦略を使用することはできません。ミューテーション イベントによってトリガーされる関数からミューテーションを実行する必要がある場合は、イベント フィルタを使用し、ミューテーションが間接的であっても自身をトリガーしないように注意してください。