使用 Cloud Functions (第 2 代) 进行扩展
借助 Cloud Functions,您可以部署代码来处理因 Firestore 数据库更改而触发的事件。这样,您无需运行自己的服务器即可添加服务器端功能。
使用 Cloud Functions (第 2 代) 扩展 Firestore
Cloud Functions (第 2 代)支持以下 Firestore 事件触发器,以便您创建与 Firestore 事件关联的处理程序:
事件类型 | 触发器 |
---|---|
google.cloud.firestore.document.v1.created |
首次写入某个文档时触发。 |
google.cloud.firestore.document.v1.updated |
当某文档已存在并且其任何值发生了更改时触发。 |
google.cloud.firestore.document.v1.deleted |
在有文档被删除时触发。 |
google.cloud.firestore.document.v1.written |
在触发 created 、updated 或 deleted 时触发。 |
google.cloud.firestore.document.v1.created.withAuthContext |
与 created 相同,但会添加身份验证信息。 |
google.cloud.firestore.document.v1.updated.withAuthContext |
与 updated 相同,但会添加身份验证信息。 |
google.cloud.firestore.document.v1.deleted.withAuthContext |
与 deleted 相同,但会添加身份验证信息。 |
google.cloud.firestore.document.v1.written.withAuthContext |
与 written 相同,但会添加身份验证信息。 |
Firestore 事件只会在文档发生更改时触发。数据未更改的 Firestore 文档更新(无操作写入)不会生成更新或写入事件。无法将事件添加到特定字段。
在事件中包含身份验证上下文
如需添加有关事件的其他身份验证信息,请使用扩展名为 withAuthContext
的事件触发器。此扩展程序会添加有关触发事件的主帐号的其他信息。除了在基本事件中返回的信息之外,它还会添加 authtype
和 authid
属性。如需详细了解属性值,请参阅 authcontext
参考文档。
编写 Firestore 触发的函数
如需编写响应 Firestore 事件的函数,请准备在部署期间指定以下内容:
- 触发器事件类型
- 用于选择与函数关联的文档的触发器事件过滤条件
- 要运行的函数代码
触发器事件过滤条件
指定事件过滤条件时,您可以指定文档完全匹配或路径模式。使用路径模式可匹配带有通配符 *
或 **
的多个文档。
例如,您可以回复对以下文档的更改:
users/marie
使用通配符 *
或 **
来响应与模式匹配的文档中的更改。通配符 *
与单个片段匹配,多片段通配符 **
与模式中的零个或多个片段匹配。
对于单个片段匹配 (*
),您还可以使用命名的捕获组。例如 users/{userId}
。
例如:
模式 | 说明 |
---|---|
/users/* 或 /users/{userId} |
匹配 /users 集合中的所有文档。与子集合(例如 /users/marie/messages/33e2IxYBD9enzS50SJ68 )中的文档不匹配 |
/users/** |
匹配 /users 集合中的所有文档以及 /users/marie/messages/33e2IxYBD9enzS50SJ68 等子集合中的文档 |
如需详细了解路径模式,请参阅 Eventarc 路径模式。
即使您使用的是通配符,触发器也必须始终指向某个文档。例如,users/{userId=*}/{messageCollectionId=*}
是无效的,因为 {messageCollectionId=*}
是一个集合。不过,users/{userId=*}/{messageCollectionId}/{messageId=*}
是有效的,因为 {messageId=*}
将始终指向某个文档。
函数示例
以下示例演示了如何接收 Firestore 事件。
如需处理事件中涉及的文档数据,请查看 value
和 old_value
字段。
value
:一个包含操作后文档快照的Document
对象。对于删除事件,不会填充此字段。old_value
:一个包含操作前文档快照的Document
对象。系统仅会针对更新和删除事件填充此字段。
Go
如需向 Firestore 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
Java
如需向 Firestore 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
Node.js
如需向 Firestore 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
使用 protobufjs 解码事件数据。在源代码中添加google.events.cloud.firestore.v1
data.proto
。
Python
如需向 Firestore 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
C#
如需向 Firestore 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
以下示例将添加到受影响文档的 original
字段的字符串转换为大写,并将新值写入同一文档:
Go
如需向 Firestore 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
Java
如需向 Firestore 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
Node.js
如需向 Firestore 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
使用 protobufjs 解码事件数据。在源代码中添加google.events.cloud.firestore.v1
data.proto
。
Python
如需向 Firestore 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
C#
如需向 Firestore 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
在源代码中添加 proto 依赖项
您必须在函数源目录中添加 Firestore data.proto
文件。此文件会导入以下 proto,您还必须将这些 proto 添加到源目录中:
请为依赖项使用相同的目录结构。例如,将 struct.proto
放置在 google/protobuf
中。
这些文件是解码事件数据所必需的。如果您的函数来源不包含这些文件,则会在运行时返回错误。
事件属性
每个事件都包含数据属性,数据属性包含事件的相关信息,例如事件触发时间。Firestore 会添加与事件中涉及的数据库和文档有关的其他数据。您可以按如下方式访问这些属性:
Java
logger.info("Function triggered by event on: " + event.getSource()); logger.info("Event type: " + event.getType()); logger.info("Event time " + event.getTime()); logger.info("Event project: " + event.getExtension("project")); logger.info("Event location: " + event.getExtension("location")); logger.info("Database name: " + event.getExtension("database")); logger.info("Database document: " + event.getExtension("document")); // For withAuthContext events logger.info("Auth information: " + event.getExtension("authid")); logger.info("Auth information: " + event.getExtension("authtype"));
Node.js
console.log(`Function triggered by event on: ${cloudEvent.source}`); console.log(`Event type: ${cloudEvent.type}`); console.log(`Event time: ${cloudEvent.time}`); console.log(`Event project: ${cloudEvent.project}`); console.log(`Event location: ${cloudEvent.location}`); console.log(`Database name: ${cloudEvent.database}`); console.log(`Document name: ${cloudEvent.document}`); // For withAuthContext events console.log(`Auth information: ${cloudEvent.authid}`); console.log(`Auth information: ${cloudEvent.authtype}`);
Python
print(f"Function triggered by change to: {cloud_event['source']}") print(f"Event type: {cloud_event['type']}") print(f"Event time: {cloud_event['time']}") print(f"Event project: {cloud_event['project']}") print(f"Location: {cloud_event['location']}") print(f"Database name: {cloud_event['database']}") print(f"Document: {cloud_event['document']}") // For withAuthContext events print(f"Auth information: {cloud_event['authid']}") print(f"Auth information: {cloud_event['authtype']}")
部署函数
部署 Cloud Functions 的用户必须具有 Cloud Functions Developer IAM 角色或具有提供相同权限的其他角色。另请参阅其他部署配置。
您可以使用 gcloud CLI 或 Google Cloud 控制台部署函数。下面的示例演示了如何使用 gcloud CLI 进行部署。如需详细了解如何使用 Google Cloud 控制台进行部署,请参阅部署 Cloud Functions 函数
gcloud
-
在 Google Cloud 控制台中,激活 Cloud Shell。
Cloud Shell 会话随即会在 Google Cloud 控制台的底部启动,并显示命令行提示符。Cloud Shell 是一个已安装 Google Cloud CLI 且已为当前项目设置值的 Shell 环境。该会话可能需要几秒钟时间来完成初始化。
使用
gcloud functions deploy
命令部署函数:gcloud functions deploy YOUR_FUNCTION_NAME \ --gen2 \ --region=FUNCTION_LOCATION \ --trigger-location=TRIGGER_LOCATION \ --runtime=YOUR_RUNTIME \ --source=YOUR_SOURCE_LOCATION \ --entry-point=YOUR_CODE_ENTRYPOINT \ --trigger-event-filters="type=EVENT_FILTER_TYPE" \ --trigger-event-filters="database=DATABASE" \ --trigger-event-filters-path-pattern="document=DOCUMENT" \
第一个参数
YOUR_FUNCTION_NAME
是已部署函数的名称。函数名称必须以字母开头,后面最多可跟 62 个字母、数字、连字符或下划线,但必须以字母或数字结尾。--gen2
标志用于指定要部署到 Cloud Functions (第 2 代)。省略此标志会导致部署到 Cloud Functions(第 1 代)。--region
标志指定要部署函数的区域。为了最大限度地提高邻近度,请设置为您的 Firestore 数据库附近的一个区域。如果您的 Firestore 数据库位于多区域位置,对于位于
nam5
的数据库,设置为us-central1
;对于位于eur3
的数据库,设置为europe-west4
。对于区域级 Firestore 位置,请设置为同一区域。--trigger-location
标志指定触发器的位置。您必须将此标志设置为 Firestore 数据库的位置。--runtime
标志指定函数使用的语言运行时。Cloud Functions 支持多种运行时;如需了解详情,请参阅运行时。--source
标志用于指定函数源代码的位置。如需了解详情,请参阅以下内容:--entry-point
标志指定源代码中函数的入口点。这是在您的函数运行时执行的代码。此标志的值必须是源代码中存在的函数名称或完全限定类名称。如需了解详情,请参阅函数入口点。EVENT_FILTER_TYPE
:Firestore 支持以下事件类型。google.cloud.firestore.document.v1.created
:首次写入某个文档时发送事件。google.cloud.firestore.document.v1.updated
:当某个文档已存在并且其值发生了更改时发送事件。google.cloud.firestore.document.v1.deleted
:当某个文档被删除时,系统会发送该事件。google.cloud.firestore.document.v1.written
:创建、更新或删除文档时发送事件。google.cloud.firestore.document.v1.created.withAuthContext
:当首次向某个文档写入数据时发送事件,并且该事件包含额外的身份验证信息google.cloud.firestore.document.v1.updated.withAuthContext
:当某个文档已存在并且其值发生了更改时发送事件。包含额外的身份验证信息google.cloud.firestore.document.v1.deleted.withAuthContext
:当某个文档被删除时,系统会发送该事件。包含额外的身份验证信息google.cloud.firestore.document.v1.written.withAuthContext
:当创建、更新或删除文档时发送事件。包含额外的身份验证信息
DATABASE
:Firestore 数据库。对于默认数据库名称,请使用(default)
。DOCUMENT
:在创建、更新或删除数据时触发事件的数据库路径。运算符可以是下列之一:- 等于;例如
--trigger-event-filters=document='users/marie'
。 - 路径模式;例如
--trigger-event-filters-path-pattern=document='users/*'
。如需了解详情,请参阅了解路径模式。
- 等于;例如
如需查看有关部署命令及其标志的完整参考信息,请参阅
gcloud functions deploy
文档。
部署示例
以下示例演示了如何使用 Google Cloud CLI 进行部署。
在 us-west2
区域中为数据库部署一个函数:
gcloud functions deploy gcfv2-trigger-firestore-node \
--gen2 \
--region=us-west2 \
--trigger-location=us-west2 \
--runtime=nodejs18 \
--source=gs://CLOUD_STORAGE_BUCKET/firestoreEventFunction.zip \
--entry-point=makeUpperCase \
--trigger-event-filters=type=google.cloud.firestore.document.v1.written \
--trigger-event-filters=database='(default)' \
--trigger-event-filters-path-pattern=document='messages/{pushId}'
在 nam5
多区域位置为数据库部署函数:
gcloud functions deploy gcfv2-trigger-firestore-python \
--gen2 \
--region=us-central1 \
--trigger-location=nam5 \
--runtime=python311 \
--source=gs://CLOUD_STORAGE_BUCKET/firestoreEventFunction.zip \
--entry-point=make_upper_case \
--trigger-event-filters=type=google.cloud.firestore.document.v1.written.withAuthContext \
--trigger-event-filters=database='(default)' \
--trigger-event-filters-path-pattern=document='messages/{pushId}'
限制
请注意适用于 Cloud Functions 的 Firestore 触发器的以下限制:
- 无法保证顺序。快速更改可能会以意想不到的顺序触发函数调用。
- 事件至少会被传送一次,但单个事件可能会导致多次调用函数。应该避免依赖“正好一次”机制,并编写幂等函数。
- Datastore 模式 Firestore 需要 Cloud Functions(第 2 代)。Cloud Functions(第 1 代)不支持 Datastore 模式。
- Cloud Functions (第 1 代) 仅适用于“(默认)”数据库,不支持 Firestore 命名数据库。请使用 Cloud Functions (第 2 代) 为命名数据库配置事件。
- 一个触发器与单一数据库相关联。您无法创建与多个数据库匹配的触发器。
- 删除数据库不会自动删除该数据库的任何触发器。触发器会停止传送事件,但会继续存在,直到您删除触发器。
- 如果匹配的事件超过请求大小上限,该事件可能不会传送到 Cloud Functions (第 1 代)。
- 因请求大小而未传送的事件会记录在平台日志中,并计入项目的日志使用量。
- 您可以在 Logs Explorer 中找到这些日志,其严重性为
error
且内容为“由于大小超出第 1 代的限制,因此事件无法传送到 Cloud Functions 函数”消息。您可以在functionName
字段下方找到函数名称。如果receiveTimestamp
字段仍在从现在起的一小时内,您可以利用该时间戳之前和之后的快照来读取相关文档,从而推断实际事件内容。 - 为避免这种情况发生,您可以:
- 迁移和升级到 Cloud Functions (第 2 代)
- 缩小文档
- 删除相关的 Cloud Functions 函数
- 您可以使用排除功能关闭日志记录功能本身,但请注意,违规事件仍然不会传送。
Eventarc 和 Firestore 位置
Eventarc 不支持多区域位置的 Firestore 事件触发器,但您仍然可以为多区域位置的 Firestore 数据库创建触发器。Eventarc 会将 Firestore 多区域位置映射到以下 Eventarc 区域:
Firestore 多区域 | Eventarc 区域 |
---|---|
nam5 |
us-central1 |
eur3 |
europe-west4 |
Cloud Functions (第 2 代) 和第 1 代函数之间的区别
Cloud Functions (第 2 代)为所有运行时使用 Eventarc 事件。以前,Cloud Functions(第 1 代)仅在部分运行时中使用 Eventarc 事件。Eventarc 事件与 Cloud Functions(第 1 代)存在以下差异。
除了 Cloud Functions 之外,适用于 Eventarc 的 Firestore 触发器支持其他目标位置。您可以将
CloudEvents
路由到多个目的地,包括但不限于 Cloud Run、GKE 和 Workflows。适用于 Eventarc 的 Firestore 触发器会在数据库写入操作开始时检索触发器定义,并使用该定义来确定 Firestore 是否应发出事件。写入操作不会考虑运行期间可能发生的任何触发器定义更改。
Cloud Functions(第 1 代)会在评估数据库写入期间检索触发器定义,并且评估期间对触发器的更改可能会影响 Firestore 是否发出事件。
如需了解详情,请参阅 Cloud Functions 版本比较。