Google Cloud Firestore 触发器(第 1 代)
Cloud Run functions 函数可以处理与该函数属于同一 Google Cloud 项目的 Firestore 中的事件。您可以使用 Firestore API 和客户端库读取或更新 Firestore,以便对这些事件做出响应。
在一个典型的生命周期中,Firestore 函数会执行以下操作:
等待特定文档发生更改。
在事件发生时触发并执行相应的任务。
接收包含受影响文档快照的数据对象。对于
write
或update
事件,该数据对象包含代表触发事件前后的文档状态的快照。
事件类型
Firestore 支持 create
、update
、delete
和 write
事件。write
事件包含对某个文档所做的所有修改。
事件类型 | 触发器 |
---|---|
providers/cloud.firestore/eventTypes/document.create (默认) |
首次写入某个文档时触发。 |
providers/cloud.firestore/eventTypes/document.update |
当某文档已存在并且其任何值发生了更改时触发。 |
providers/cloud.firestore/eventTypes/document.delete |
当文档的数据被删除时触发。 |
providers/cloud.firestore/eventTypes/document.write |
在创建、更新或删除某个文档时触发。 |
在触发器中,通配符是使用大括号编写的,如下所示:
"projects/YOUR_PROJECT_ID/databases/(default)/documents/collection/{document_wildcard}"
指定文档路径
如需触发您的函数,请指定要侦听的文档路径。函数只会对文档更改做出响应,无法监控特定的字段或集合。以下是一些有效和无效的文档路径示例:
users/marie
:有效的触发器。监控单个文档 (/users/marie
)。users/{username}
:有效的触发器。监控所有用户文档。通配符用于监控集合中的所有文档。users/{username}/addresses
:无效的触发器。该路径指向的是子集合addresses
,而不是某个文档。users/{username}/addresses/home
:有效的触发器。监控所有用户的家庭住址文档。users/{username}/addresses/{addressId}
:有效的触发器。监控所有地址文档。
使用通配符和参数
如果您不确定要监控的具体文档是哪个,请使用 {wildcard}
代替文档 ID:
users/{username}
侦听所有用户文档的更改。
在此示例中,如果 users
中的任何文档的任何字段发生更改,都会与一个名为 {username}
的通配符相匹配。
如果 users
中的某个文档有多个子集合,并且这些子集合中一个文档内的某字段发生了更改,那么不会触发 {username}
通配符。
通配符匹配项会从文档路径中提取出来。您可以定义任意多个通配符,以替代明确指定的集合或文档 ID。
事件结构
当发生类似于如下所示的事件时,此触发器会调用您的函数:
{ "oldValue": { // Update and Delete operations only A Document object containing a pre-operation document snapshot }, "updateMask": { // Update operations only A DocumentMask object that lists changed fields. }, "value": { // A Document object containing a post-operation document snapshot } }
每个 Document
对象都包含一个或多个 Value
对象。如需查看类型参考信息,请参阅 Value
文档。如果您使用类型化语言(例如 Go)编写函数,此方法特别有用。
代码示例
以下示例 Cloud Functions 函数会输出 Cloud Firestore 触发事件的字段:
Node.js
Python
Go
Java
C#
Ruby
PHP
以下示例会检索用户添加的值,将该位置的字符串转换为大写,然后将该值替换为该大写字符串:
Node.js
Python
Go
Java
C#
Ruby
PHP
部署函数
以下 gcloud
命令会部署一个由文档 /messages/{pushId}
上的写入事件触发的函数:
gcloud functions deploy FUNCTION_NAME \ --no-gen2 \ --entry-point ENTRY_POINT \ --runtime RUNTIME \ --set-env-vars GOOGLE_CLOUD_PROJECT=YOUR_PROJECT_ID \ --trigger-event "providers/cloud.firestore/eventTypes/document.write" \ --trigger-resource "projects/YOUR_PROJECT_ID/databases/(default)/documents/messages/{pushId}"
参数 | 说明 |
---|---|
FUNCTION_NAME |
您要部署的 Cloud Functions 函数的注册名称。这可以是源代码中函数的名称,也可以是任意字符串。如果 FUNCTION_NAME 是任意字符串,则必须添加 --entry-point 标志。 |
--entry-point ENTRY_POINT |
源代码中函数或类的名称。可选,除非您未使用 FUNCTION_NAME 指定源代码中要在部署期间执行的函数。在这种情况下,您必须使用 --entry-point 提供可执行函数的名称。 |
--runtime RUNTIME |
您使用的运行时的名称。如需完整列表,请参阅 gcloud 参考文档。 |
--set-env-vars GOOGLE_CLOUD_PROJECT=YOUR_PROJECT_ID |
项目的唯一标识符,作为运行时环境变量。 |
--trigger-event NAME |
函数将监控的事件类型(write 、create 、update 或 delete 之一)。 |
--trigger-resource NAME |
函数将侦听的完全限定数据库路径。此路径应符合以下格式:
"projects/YOUR_PROJECT_ID/databases/(default)/documents/PATH"
{pushId} 文本是上面的指定文档路径中所述的通配符参数。 |
限制
请注意适用于 Cloud Run functions 的 Firestore 触发器的以下限制:
- Cloud Run functions (第 1 代) 前提条件是 Firestore 原生模式的现有“(默认)”数据库。它不支持 Firestore 命名数据库或 Datastore 模式。在这种情况下,请使用 Cloud Run functions (第 2 代) 来配置事件。
- 无法保证顺序。快速更改可能会以意想不到的顺序触发函数调用。
- 事件至少会被传送一次,但单个事件可能会导致多次调用函数。应该避免依赖“正好一次”机制,并编写幂等函数。
- Datastore 模式 Firestore 需要 Cloud Run functions(第 2 代)。Cloud Run functions(第 1 代)不支持 Datastore 模式。
- 一个触发器与单一数据库相关联。您无法创建与多个数据库匹配的触发器。
- 删除数据库不会自动删除该数据库的任何触发器。触发器会停止传送事件,但会继续存在,直到您删除触发器。
- 如果匹配的事件超过请求大小上限,该事件可能不会传送到 Cloud Run functions (第 1 代)。
- 因请求大小而未传送的事件会记录在平台日志中,并计入项目的日志使用量。
- 您可以在 Logs Explorer 中找到这些日志,其严重性为
error
且内容为“由于大小超出第 1 代的限制,因此事件无法传送到 Cloud Functions 函数”消息。您可以在functionName
字段下方找到函数名称。如果receiveTimestamp
字段仍在从现在起的一小时内,您可以利用该时间戳之前和之后的快照来读取相关文档,从而推断实际事件内容。 - 为避免这种情况发生,您可以:
- 迁移和升级到 Cloud Run functions (第 2 代)
- 缩小文档
- 删除相关的 Cloud Run functions 函数
- 您可以使用排除功能关闭日志记录功能本身,但请注意,违规事件仍然不会传送。