建立及處理自訂事件觸發條件

有了 Cloud Functions (第 2 代),您就可以根據自訂事件觸發函式。這些是特殊或額外事件供應器提供的事件,而非 Cloud FunctionsFirebase SDK 原生支援的 Firebase 事件。透過自訂事件觸發條件,應用程式可以回應 Firebase Extensions 提供的事件,或者您也可以發布自己的自訂事件,並觸發回應這些事件的功能。

所有自訂事件都符合 CloudEvents JSON 事件格式,並發布至 EventarcEventarc 需支付使用費

使用自訂事件觸發函式

您可以發布自訂事件 (或從 Firebase 擴充功能取得事件),並實作這項基本流程,以便觸發回應這些事件的函式:

  1. 將所需事件發布至 Eventarc 管道,或找出已安裝擴充功能提供的事件。
  2. 在函式程式碼中,使用事件處理常式訂閱 Eventarc 管道上的事件。
  3. 在函式中剖析 CloudEvent 物件中傳回的酬載,並執行應用程式所需的任何自訂邏輯。

舉例來說,遊戲應用程式可能會在使用者進入或離開前十名競爭對手排行榜時,傳送通知給使用者。這個應用程式可以將排行榜事件發布至預設管道,然後在向使用者傳送指定推播通知的函式中處理事件。

舉另一個例子來說,用於協助應用程式處理大型圖片的擴充功能,可能會在圖片大小調整完成時發出事件。安裝此擴充功能的應用程式可透過更新應用程式中的連結,將其指向已調整大小的圖片版本,藉此處理完成事件。

將事件發布至管道

Eventarc 事件會發布至管道。管道是一種將相關事件分組並管理存取權限的方式。當您安裝擴充功能或部署使用自訂事件的函式時,Firebase 會在 us-central1 區域中自動建立名為 firebase 的預設管道。Firebase Admin SDK 提供 eventarc 子套件,可用於發布至管道。

如要使用預設管道,從信任的伺服器 (或其他函式) 發布事件,請按照下列步驟操作:

import {getEventarc} from 'firebase-admin/eventarc';

getEventarc().channel().publish({
    type: 'achieved-leaderboard',
    subject: 'Welcome to the top 10',
    data: {
      message: 'You have achieved the nth position in our leaderboard!  To see . . .'
    }
});

除了自動建立預設管道之外,Firebase 也會設定環境變數 EVENTARC_CLOUD_EVENT_SOURCE,用來指定事件來源。如果您要發布 Cloud Functions for Firebase 以外的事件,就必須在事件酬載中明確加入 source 欄位。

處理自訂事件

您可以使用 onCustomEventPublishedon_custom_event_published 處理常式來處理所有自訂事件,包括擴充功能事件。首先,請從 Eventarc SDK 匯入此處理常式,並搭配使用 Firebase Admin SDK

Node.js

const {onCustomEventPublished} = require("firebase-functions/v2/eventarc");
const logger = require("firebase-functions/logger");
const {initializeApp} = require("firebase-admin/app");
const {getFirestore} = require("firebase-admin/firestore");

Python

from firebase_admin import firestore, initialize_app
from firebase_functions import eventarc_fn

在函式程式碼中,傳入事件名稱,如範例函式所示:

Node.js

exports.onimageresized = onCustomEventPublished(
    "firebase.extensions.storage-resize-images.v1.complete",
    (event) => {
      logger.info("Received image resize completed event", event);
      // For example, write resized image details into Firestore.
      return getFirestore()
          .collection("images")
          .doc(event.subject.replace("/", "_")) // original file path
          .set(event.data); // resized images paths and sizes
    });

Python

@eventarc_fn.on_custom_event_published(
    event_type="firebase.extensions.storage-resize-images.v1.complete")
def onimageresized(event: eventarc_fn.CloudEvent) -> None:
    print("Received image resize completed event: ", event.type)

    if not isinstance(event.subject, str):
        print("No 'subject' data.")
        return

    # For example, write resized image details into Firestore.
    firestore_client: google.cloud.firestore.Client = firestore.client()
    collection = firestore_client.collection("images")
    doc = collection.document(event.subject.replace("/", "_"))  # original file path
    doc.set(event.data)  # resized images paths and sizes

對於每個特定擴充功能,事件物件中傳回的酬載會提供可用於為應用程式流程執行自訂邏輯的資料。在這種情況下,函式會使用 Admin SDK 將有關已調整大小圖片的中繼資料複製到 Cloud Firestore 中的集合,從事件提供的 subject 取得檔案名稱,並從事件提供的 data 儲存中繼資料。

在非預設管道上發布及處理事件

如果您有特殊權限需求或其他需求,且不希望所有事件都具有相同的顯示層級和存取權,自訂管道就很實用。您可以使用 Google Cloud 控制台建立自己的管道。事件的發布和訂閱必須在同一個管道中進行。

如果自訂事件是在非預設管道上發布,您必須在函式程式碼中指定管道。舉例來說,如果您想處理在 us-west1 位置的非預設管道中發布的事件,就必須如以下所示指定管道:

Node.js

import { onCustomEventPublished } from "firebase-functions/v2/eventarc";

export const func = onCustomEventPublished(
    {
      eventType: "firebase.extensions.storage-resize-images.v1.complete",
      channel: "locations/us-west1/channels/firebase",
      region: "us-west1",
    },
    (event) => { ... });

Python

@eventarc_fn.on_custom_event_published(
    event_type="firebase.extensions.storage-resize-images.v1.complete",
    channel="locations/us-west1/channels/firebase",
    region="us-west1")
def onimageresizedwest(event: eventarc_fn.CloudEvent) -> None:
    print("Received image resize completed event: ", event.type)
    # ...