如何在 Cloud 函数中读取 Firestore 文档更新之前/之后的值?

Posted

技术标签:

【中文标题】如何在 Cloud 函数中读取 Firestore 文档更新之前/之后的值?【英文标题】:How to read before/after values of a firestore document update in a Cloud function? 【发布时间】:2021-01-17 02:36:51 【问题描述】:

此谷歌云功能(Node.js 12)在更新 Firestore 文档时触发。

但是它在执行时会抛出错误消息:

TypeError: Cannot read property 'data' of undefined at exports.ChangeHandlerFn

我正在尝试检索更新文档的前后值。

/**
 * Nodejs function triggered by a change to a Firestore document.
*/
exports.ChangeHandlerFn = (event, context) => 
  
  const resource = context.resource;
  // log the full event object - this logs correctly.
  console.log("JSON.stringify(event): " + JSON.stringify(event));

 // The following line throws error 
  const beforeValue = event.before.data();
  const afterValue = event.after.data();

 //This doesn't work either - using val()
 // const beforeValue = event.before.val();
 // const afterValue = event.after.val();

;

如何获取文档更新前后的值?

代码通过以下方式部署: Google Cloud Console 用户界面 > 云功能。

触发器定义(在 Google Cloud Console 中): Cloud Firestore 测试版 事件类型:更新 文件路径:vehicles/owner

Firestore 详细信息 Firestore 数据结构:

vehicles(collection) > abc@email.com (document) > COLOR_1 (field)

                     > def@email.com (document) > COLOR_1 (field)

当 abc@email.com(document) 的 COLOR_1 字段值从 1 更改为 0 此语句的输出: console.log("JSON.stringify(event): " + JSON.stringify(event)); 如下:


   "oldValue":
      "createTime":"2020-09-28T13:29:41.306218Z",
      "fields":
         "COLOR_1":
            "integerValue":"1"
         
      ,
      "name":"projects/vehicles-990a1/databases/(default)/documents/vehicles/abc@email.com",
      "updateTime":"2020-10-01T06:51:50.092527Z"
   ,
   "updateMask":
      "fieldPaths":[
         "COLOR_1"
      ]
   ,
   "value":
      "createTime":"2020-09-28T13:29:41.306218Z",
      "fields":
         "COLOR_1":
            "integerValue":"0"
         
      ,
      "name":"projects/vehicles-990a1/databases/(default)/documents/vehicles/abc@email.com",
      "updateTime":"2020-10-01T06:51:50.092527Z"
   
```

【问题讨论】:

乍一看,您的代码似乎也在创建/删除文档时被触发。您能展示一下您使用的 Cloud Functions 触发器吗? 请编辑问题以显示您用于部署此功能的命令。 在问题中添加了有关部署和触发器定义的其他信息。已通过对文档的更新操作对此进行了测试 - 如上所述,该函数会触发并引发错误。如您所见,事件对象的 JSON 字符串确实为我们提供了旧(之前)/新(之后)值,但不确定为什么 event.before.data() 或 event.after.data() 不起作用。跨度> 【参考方案1】:

如果您使用 Google Cloud 工具(不是 Firebase 工具)编写函数,那么您应该观察 Google Cloud documentation(不是 Firebase 文档)中的事件对象结构:


    "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
    

您应该使用 event.oldValueevent.value,而不是 event.beforeevent.after(它们是 Firebase 名称)。

那里的对象可能也没有 data() 方法(这也是 Firebase 的东西)。 Google Cloud 文档说:

每个 Document 对象包含一个或多个 Value 对象。有关类型引用,请参阅 Value documentation。如果您使用类型化语言(如 Go)来编写函数,这将特别有用。

【讨论】:

感谢您的帮助。这有效:event.value.nameevent.oldValue.fields.COLOR_1.integerValue

以上是关于如何在 Cloud 函数中读取 Firestore 文档更新之前/之后的值?的主要内容,如果未能解决你的问题,请参考以下文章

在 Cloud Function 的一个功能中执行数千次读取和删除 Firestore 操作是不是可以?

Cloud Firestore 安全规则 -(读取、写入)

我们会为仅从缓存中读取(Cloud FireStore)支付(成本)吗? [复制]

Cloud Firestore 中 get() 和 onSnapshot() 的区别

Cloud Firestore 每次读取定价

使用 exists() 的 Cloud Firestore 规则是不是算作读取?