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

使用 Cloud Functions (第 2 代) 時,您可以觸發函式來回應自訂事件。這些事件是由特殊或額外的事件供應商提供,而非 Firebase SDK for Cloud Functions 原生支援的 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)
    # ...