擴充資料連接與雲端函數

您可以使用 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 處理常式可設定選項,根據特定屬性篩選事件。如果您只想針對特定變動觸發函式,這項功能就非常實用。

你可以依據 serviceconnectoroperation 篩選:

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,如下所示:

發起變動的 authtype authid
通過驗證的使用者 app_user Firebase Auth 權杖 UID
未通過驗證的使用者 unauthenticated 空白
Admin SDK 模擬使用者 app_user 遭模擬使用者的 Firebase 驗證權杖 UID
Admin SDK 模擬未經驗證的請求 unauthenticated 空白
具備完整權限的 Admin SDK admin 空白

存取事件資料

傳遞至函式的 CloudEvent 物件包含觸發事件的相關資訊。

活動屬性

屬性 類型 說明
id string 事件的專屬 ID。
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 觸發事件的主體專屬 ID。
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 FirestoreRealtime Database 等其他資料庫觸發程序不同,Data Connect 事件不會提供資料的「之前」快照。由於 Data Connect 會將要求 Proxy 至基礎資料庫,因此無法以交易方式取得資料的「之前」快照。您只能存取傳送至變異的引數,以及變異傳回的資料。

因此,您無法使用比較「之前」和「之後」快照的策略,避免無限迴圈 (事件觸發器觸發相同事件)。如果必須從由突變事件觸發的函式執行突變,請使用事件篩選器,並確保突變絕不會觸發自身,即使是間接觸發也一樣。