有了 Cloud Functions (第 2 代),您就可以根據自訂事件觸發函式。這些是特殊或額外事件供應器提供的事件,而非 Cloud Functions 的 Firebase SDK 原生支援的 Firebase 事件。透過自訂事件觸發條件,應用程式可以回應 Firebase Extensions 提供的事件,或者您也可以發布自己的自訂事件,並觸發回應這些事件的功能。
所有自訂事件都符合 CloudEvents JSON 事件格式,並發布至 Eventarc。Eventarc 需支付使用費。
使用自訂事件觸發函式
您可以發布自訂事件 (或從 Firebase 擴充功能取得事件),並實作這項基本流程,以便觸發回應這些事件的函式:
- 將所需事件發布至 Eventarc 管道,或找出已安裝擴充功能提供的事件。
- 在函式程式碼中,使用事件處理常式訂閱 Eventarc 管道上的事件。
- 透過函式,剖析 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
欄位。
處理自訂事件
您可以使用 onCustomEventPublished
或 on_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)
# ...