建立和處理自訂事件觸發器

借助 Cloud Functions(第二代),您可以觸發函數來回應自訂事件。這些事件是由特殊或附加事件提供者提供的事件,而不是 Firebase SDK for Cloud Functions 本身支援的 Firebase 事件。透過自訂事件觸發器,您的應用程式可以回應 Firebase Extensions 提供的事件,也可以發布您自己的自訂事件並觸發函數來回應它們。

所有自訂事件均符合CloudEvents JSON 事件格式並發佈到Eventarc 。需支付 Eventarc使用費

使用自訂事件觸發函數

您可以透過實作以下基本流程來發布自訂事件(或從 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)
    # ...