Firestore 触发器(第 2 代)
您可以配置 Cloud Functions 函数,使其由 Firestore 数据库中的事件触发。触发后,您的函数可以通过 Firestore API 和客户端库读取和更新 Firestore 数据库,以便对这些事件做出响应。
在一个典型的生命周期中,Firestore 函数会执行以下操作:
等待特定文档发生更改。
在事件发生时触发并执行相应的任务。
接收包含受影响文档快照的数据对象。对于
write
或update
事件,该数据对象包含代表触发事件前后的文档状态的快照。
事件类型
Firestore 支持 create
、update
、delete
和 write
事件。write
事件包含对某个文档所做的所有修改。
事件类型 | 触发器 |
---|---|
google.cloud.firestore.document.v1.created (默认) |
首次写入某个文档时触发。 |
google.cloud.firestore.document.v1.updated |
当某文档已存在并且其任何值发生了更改时触发。 |
google.cloud.firestore.document.v1.deleted |
当文档的数据被删除时触发。 |
google.cloud.firestore.document.v1.written |
在创建、更新或删除某个文档时触发。 |
在触发器中,通配符是使用大括号编写的,如下所示:
"projects/YOUR_PROJECT_ID/databases/(default)/documents/collection/{document_wildcard}"
指定文档路径
如需触发您的函数,请指定要侦听的文档路径。文档路径必须与函数位于同一 Google Cloud 项目中。
以下是一些有效和无效的文档路径示例:
users/marie
:有效的触发器。监控单个文档 (/users/marie
)。users/{username}
:有效的触发器。监控所有用户文档。通配符用于监控集合中的所有文档。users/{username}/addresses
:无效的触发器。该路径指向的是子集合addresses
,而不是某个文档。users/{username}/addresses/home
:有效的触发器。监控所有用户的家庭住址文档。users/{username}/addresses/{addressId}
:有效的触发器。监控所有地址文档。users/{user=**}
:有效的触发器。监控所有用户文档以及每个用户文档下子集合中的任何文档,例如/users/userID/address/home
或/users/userID/phone/work
。
通配符和参数
如果您不知道要监控的特定文档,请使用 {wildcard}
代替文档 ID:
users/{username}
侦听所有用户文档的更改。
在此示例中,如果 users
中的任何文档的任何字段发生更改,都会与一个名为 {username}
的通配符相匹配。
如果 users
中的某个文档有多个子集合,并且这些子集合中一个文档内的某字段发生了更改,那么不会触发 {username}
通配符。 如果您的目标是同时也响应子集合中的事件,请使用多段通配符 {username=**}
。
通配符匹配项会从文档路径中提取出来。 您可以定义任意多个通配符,以替代明确指定的集合或文档 ID。最多可以使用一个多段通配符,例如 {username=**}
。
事件结构
当发生如下所示的事件时,此触发器会调用您的函数:
{ "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)编写函数,此方法特别有用。
设置您的 Firestore 数据库
您需要一个 Firestore 数据库来测试本文档中的示例。您必须先设置好 Cloud Firestore 数据库,然后再部署函数。如果您还没有 Firestore 数据库,请按如下方式创建一个:
点击选择原生模式。
选择数据库位于的区域(位置)。一旦选择便无法更改。
点击创建数据库。
Firestore 数据模型由包含文档的集合组成。每个文档包含一组键值对。
当您对指定集合内的文档进行更改时,会触发您在本教程中创建的函数。
示例 1:Hello Firestore 函数
以下示例 Cloud Functions 函数会输出触发 Firestore 事件的字段:
部署 Hello Firestore 函数
设置 Firestore 数据库(如果您尚未这样做)。
如需使用 Firestore 触发器部署 Hello Firestore 函数,请在包含示例代码(如果是 Java,则为
pom.xml
文件)的目录中运行以下命令:gcloud functions deploy FUNCTION_NAME \ --gen2 \ --runtime=RUNTIME \ --region=REGION \ --trigger-location=TRIGGER REGION \ --source=. \ --entry-point=ENTRY_POINT \ --trigger-event-filters=type=google.cloud.firestore.document.v1.written \ --trigger-event-filters=database='(default)' \ --trigger-event-filters-path-pattern=document='users/{username}'
替换以下内容:
FUNCTION_NAME
:已部署函数的名称。RUNTIME
:您的函数使用的语言运行时。REGION
:要在其中部署函数的区域。TRIGGER_REGION
:触发器的位置,必须与 Firestore 数据库的区域相同。ENTRY_POINT
:源代码中函数的入口点。这是在您的函数运行时执行的代码。
按原样使用其他字段:
--trigger-event-filters=type=google.cloud.firestore.document.v1.written
指定根据google.cloud.firestore.document.v1.written
事件类型创建、更新或删除文档时触发函数。--trigger-event-filters=database='(default)'
指定 Firebase 数据库。对于默认数据库名称,请使用(default)
。--trigger-event-filters-path-pattern=document='users/{username}'
提供受监控文档的路径模式,应监控这些文档是否发生相关改变。此路径模式声明users
集合中的所有文档都应被监控。如需了解详情,请参阅了解路径模式。
测试 Hello Firestore 函数
如需测试 Hello Firestore 函数,请在 Firestore 数据库中设置一个名为 users
的集合:
在“Firestore 数据”页面上,点击开始使用集合。
指定
users
作为集合 ID。如需开始添加集合的第一个文档,请在为其添加首个文档下接受自动生成的文档 ID。
为文档至少添加一个字段,并指定名称和值。在此示例中,名称为“username”,值为“rowan”:
完成之后,点击保存。
此操作会创建一个新文档,从而触发您的函数。
如需确认您的函数已触发,请在 Google Cloud 控制台 Cloud Functions 概览页面中点击该函数的链接名称,以打开函数详情页面。
打开日志标签页,然后查找此字符串:
Function triggered by change to: //firestore.googleapis.com/projects/your-project-id/databases/(default)'
示例 2:“转换为大写”函数
以下示例会检索用户添加的值,将该位置的字符串转换为大写,然后将该值替换为该大写字符串:
部署“转换为大写”函数
设置 Firestore 数据库(如果您尚未这样做)。
使用以下命令部署由文档
companies/{CompanyId}
上的写入事件触发的函数:gcloud functions deploy FUNCTION_NAME \ --gen2 \ --runtime=RUNTIME \ --trigger-location=TRIGGER REGION \ --region=REGION \ --source=. \ --entry-point=ENTRY_POINT \ --trigger-event-filters=type=google.cloud.firestore.document.v1.written \ --trigger-event-filters=database='(default)' \ --trigger-event-filters-path-pattern=document='messages/{pushId}'
替换以下内容:
FUNCTION_NAME
:已部署函数的名称。RUNTIME
:您的函数使用的语言运行时。REGION
:要在其中部署函数的区域。TRIGGER_REGION
:触发器的位置,必须与 Firestore 数据库的区域相同。ENTRY_POINT
:源代码中函数的入口点。这是在您的函数运行时执行的代码。
按原样使用其他字段:
--trigger-event-filters=type=google.cloud.firestore.document.v1.written
指定根据google.cloud.firestore.document.v1.written
事件类型创建、更新或删除文档时触发函数。--trigger-event-filters=database='(default)'
指定 Firestore 数据库。对于默认数据库名称,请使用(default)
。--trigger-event-filters-path-pattern=document='messages/{pushId}'
提供受监控文档的路径模式,应监控这些文档是否发生相关改变。此路径模式声明messages
集合中的所有文档都应被监控。如需了解详情,请参阅了解路径模式。
测试“转换为大写”函数
如需测试刚刚部署的“转换为大写”函数,请在 Firestore 数据库中设置一个名为 messages
的集合:
点击开始使用集合。
指定
messages
作为集合 ID。如需开始添加集合的第一个文档,请在为其添加首个文档下接受自动生成的文档 ID。
如需触发已部署的函数,请添加一个文档,其字段名称为“original”且字段值为小写字母单词,例如:
保存文档时,您可以看到值字段中的小写字词转换为大写字词。
如果您随后修改字段值以包含小写字母,则会再次触发该函数,并将所有小写字母转换为大写字母。
限制
请注意适用于 Cloud Functions 的 Firestore 触发器的以下限制:
- Cloud Functions (第 1 代) 前提条件是 Firestore 原生模式的现有“(默认)”数据库。它不支持 Firestore 命名数据库或 Datastore 模式。在这种情况下,请使用 Cloud Functions (第 2 代) 来配置事件。
- 无法保证顺序。快速更改可能会以意想不到的顺序触发函数调用。
- 事件至少会被传送一次,但单个事件可能会导致多次调用函数。应该避免依赖“正好一次”机制,并编写幂等函数。
- Datastore 模式 Firestore 需要 Cloud Functions(第 2 代)。Cloud Functions(第 1 代)不支持 Datastore 模式。
- 一个触发器与单一数据库相关联。您无法创建与多个数据库匹配的触发器。
- 删除数据库不会自动删除该数据库的任何触发器。触发器会停止传送事件,但会继续存在,直到您删除触发器。
- 如果匹配的事件超过请求大小上限,该事件可能不会传送到 Cloud Functions(第 1 代)。
- 因请求大小而未传送的事件会记录在平台日志中,并计入项目的日志使用量。
- 您可以在 Logs Explorer 中找到这些日志,其严重性为
error
且内容为“由于大小超出第 1 代的限制,因此事件无法传送到 Cloud Functions 函数”消息。您可以在functionName
字段下方找到函数名称。如果receiveTimestamp
字段仍在从现在起的一小时内,您可以利用该时间戳之前和之后的快照来读取相关文档,从而推断实际事件内容。 - 为避免这种情况发生,您可以:
- 迁移和升级到 Cloud Functions (第 2 代)
- 缩小文档
- 删除相关的 Cloud Functions 函数
- 您可以使用排除功能关闭日志记录功能本身,但请注意,违规事件仍然不会传送。