Firebase 即時資料庫觸發條件
您可以使用 Cloud Run 函式,在與函式相同的 Google Cloud 專案中處理 Firebase 即時資料庫中的事件。Cloud Run 函式可讓您以完整的管理權限執行資料庫作業,並確保資料庫的每項變更都會個別處理。您可以透過 Firebase Admin SDK 變更 Firebase 即時資料庫。
在一般生命週期中,Firebase 即時資料庫函式會執行下列操作:
等待對特定資料庫位置的變更。
在事件發生時觸發並執行它的工作。
接收包含儲存在指定文件中之資料快照的資料物件。
事件類型
函式可讓您以兩個明確性層級處理資料庫事件;您可以明確接聽僅建立、更新或刪除事件,也可以接聽任何種類路徑的任何變更。Cloud Run 函式支援 Realtime Database 的以下事件類型:
事件類型 | 觸發條件 |
---|---|
providers/google.firebase.database/eventTypes/ref.write |
針對任何異動事件觸發:當在即時資料庫中建立、更新或刪除資料時。 |
providers/google.firebase.database/eventTypes/ref.create (預設) |
當在即時資料庫中建立新資料時觸發。 |
providers/google.firebase.database/eventTypes/ref.update |
當在即時資料庫中更新資料時觸發。 |
providers/google.firebase.database/eventTypes/ref.delete |
當在即時資料庫中刪除資料時觸發。 |
指定資料庫路徑與執行個體
如要控制您函式應觸發的時機與位置,需要指定路徑,然後選擇性地指定資料庫執行個體。
路徑
路徑規格會與涉及路徑的「所有」寫入內容進行比對,其中包括在其下方任何位置發生的寫入。如果您將函式的路徑設為 /foo/bar
,則會比對下列兩個位置的事件:
/foo/bar
/foo/bar/baz/really/deep/path
無論是哪種情況,Firebase 都會解讀事件發生在 /foo/bar
,而事件資料會包含 /foo/bar
的舊資料和新資料。如果事件資料比較大,請考慮使用較深路徑的多個函式,而不是靠近資料庫根目錄的單一函式。如要獲得最佳效能,請僅要求可能的最深層級資料。
您可以將路徑元件指定為萬用字元,方法是將其前後加上大括號;foo/{bar}
會比對 /foo
的任何子項。這些萬用字元路徑元件的值會顯示在函式的 event.params
物件中。在這個範例中,值為 event.params.bar
。
使用萬用字元的路徑可以與單一寫入內容中的多個事件進行比對。插入:
{
"foo": {
"hello": "world",
"firebase": "functions"
}
}
比對路徑 /foo/{bar}
兩次:一次使用 "hello": "world"
,另一次使用 "firebase": "functions"
。
執行個體
使用 Google Cloud 控制台時,必須指定資料庫例項。
使用 Google Cloud CLI 時,必須將執行個體指定為 --trigger-resource
字串的一部分。
例如,以下會在 --trigger-resource
字串中使用下列內容:
--trigger-resource projects/_/instances/DATABASE_INSTANCE/refs/PATH
事件結構
處理即時資料庫事件時,data
物件會包含兩個以 JSON 物件格式提供的屬性:
data
:在觸發函式的事件發生前,擷取的資料快照。delta
:觸發函式的事件發生後所擷取的資料快照。
程式碼範例
Node.js
Python
Go
Java
C#
using CloudNative.CloudEvents; using Google.Cloud.Functions.Framework; using Google.Events.Protobuf.Firebase.Database.V1; using Microsoft.Extensions.Logging; using System.Threading; using System.Threading.Tasks; namespace FirebaseRtdb; public class Function : ICloudEventFunction<ReferenceEventData> { private readonly ILogger _logger; public Function(ILogger<Function> logger) => _logger = logger; public Task HandleAsync(CloudEvent cloudEvent, ReferenceEventData data, CancellationToken cancellationToken) { _logger.LogInformation("Function triggered by change to {subject}", cloudEvent.Subject); _logger.LogInformation("Delta: {delta}", data.Delta); // In this example, we don't need to perform any asynchronous operations, so the // method doesn't need to be declared async. return Task.CompletedTask; } }
Ruby
PHP
use Google\CloudFunctions\CloudEvent; function firebaseRTDB(CloudEvent $cloudevent) { $log = fopen(getenv('LOGGER_OUTPUT') ?: 'php://stderr', 'wb'); fwrite($log, 'Event: ' . $cloudevent->getId() . PHP_EOL); $data = $cloudevent->getData(); $resource = $data['resource'] ?? '<null>'; fwrite($log, 'Function triggered by change to: ' . $resource . PHP_EOL); $isAdmin = isset($data['auth']['admin']) && $data['auth']['admin'] == true; fwrite($log, 'Admin?: ' . var_export($isAdmin, true) . PHP_EOL); fwrite($log, 'Delta: ' . json_encode($data['delta'] ?? '') . PHP_EOL); }
部署函式
下列 gcloud 指令會部署函式,該函式會在路徑 /messages/{pushId}/original
上由 create
事件觸發:
gcloud functions deploy FUNCTION_NAME \ --no-gen2 \ --entry-point ENTRY_POINT \ --trigger-event providers/google.firebase.database/eventTypes/ref.create \ --trigger-resource projects/_/instances/DATABASE_INSTANCE/refs/messages/{pushId}/original \ --runtime RUNTIME
引數 | 說明 |
---|---|
FUNCTION_NAME |
您要部署的 Cloud Run 函式註冊名稱。這可以是原始碼中的函式名稱,也可以是任意字串。如果 FUNCTION_NAME 是任意字串,則必須加入 --entry-point 旗標。 |
--entry-point ENTRY_POINT |
原始碼中函式或類別的名稱。選用,除非您未使用 FUNCTION_NAME 指定要於部署期間執行的原始碼中的函式。在這種情況下,您必須使用 --entry-point 提供可執行函式的名稱。 |
--trigger-event NAME |
函式希望接收的事件類型名稱。在這種情況下,會是下列其中一種:寫入、建立、更新或刪除。 |
--trigger-resource NAME |
函式要監聽的完整資料庫路徑。格式應符合下列格式:projects/_/instances/DATABASE_INSTANCE/refs/PATH 。 |
--runtime RUNTIME |
您使用的執行階段名稱。如需完整清單,請參閱 gcloud 參考資料。 |