【问题标题】:Cloud Functions get list from firestore pathCloud Functions 从 Firestore 路径获取列表
【发布时间】:2020-08-04 05:40:30
【问题描述】:

我的 Firestore 中有这个架构:test1/{test1ID}/test2/

每当有新数据添加到 test1ID 时,我都想在云函数中与我的 firestore 进行交互。

我的目标是更新更新数据的 test1ID 文档,其值为 [0]th + [1]th + [2]th 子集合 test2 下的文档。

但是使用下面的代码,我得到 test2 文档列表(currentTest2DocumentList)未定义。

(错误消息 => TypeError:无法读取未定义的属性“0”)

如何获取子集合下的有效文档列表?

const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp();

exports.onItemDocumentUpdate = functions.firestore.document('test1/{test1ID}')
.onUpdate(async (change, context) => {

const currentTest1ID = context.params.test1ID


const currentTest2DocumentList = await 
admin.firestore().collection('test1').doc(currentTest1ID).collection('test2').get()
.then(function(docs) {return docs.forEach(function (doc){doc.data()})})

const addedValue = currentTest2DocumentList[0].field1 + currentTest2DocumentList[1].field1 + 
currentTest2DocumentList[2].field1

return admin.firestore().collection('test1').doc(currentTest1ID).update({testField: 
addedValue});

【问题讨论】:

    标签: javascript google-cloud-firestore google-cloud-functions


    【解决方案1】:

    您似乎没有正确使用 forEach。试试这个:

    const currentTest2DocumentList = await
    admin.firestore().collection('test1').doc(currentTest1ID).collection('test2').get()
    .then(function(docs) {
      let res = []
      docs.forEach(doc => res.push(doc.data()));
      return res;
    })
    

    甚至更好:

    const currentTest2DocumentList = await
    admin.firestore().collection('test1').doc(currentTest1ID).collection('test2').get()
    .then(docs => docs.map(doc => doc.data()));
    

    test2 集合中的文档是否超过 3 个?因为那样阅读所有这些似乎是一种浪费。您可以添加limit(3) 来解决此问题

    const currentTest2DocumentList = await
    admin.firestore().collection('test1').doc(currentTest1ID).collection('test2').limit(3).get()
    .then(docs => docs.map(doc => doc.data()));
    

    【讨论】:

      【解决方案2】:

      这行代码没有达到你的预期:

      const currentTest1ID = context.params.ID
      

      我建议记录currentTest1ID。它将是未定义的。这是因为context.params 仅包含文档路径中由通配符标记的键。您没有任何名为“ID”的通配符。也许这就是你想要的:

      const currentTest1ID = context.params.test1ID
      

      请注意,test1ID 与您在函数路径中定义的通配符匹配。

      【讨论】:

      • 哦,谢谢指正。我编辑了问题。我在为 StackOverflow 提问时犯了一个错误,但即使使用更正的问题“currentTest2DocumentList”仍然无法识别。有什么建议吗?
      【解决方案3】:

      返回 undefined 的原因是 forEach 函数没有返回任何值。尝试访问集合快照的 docs 字段并使用 javascript map 函数,如下所示:

      // IMPORT
      const functions = require('firebase-functions');
      const admin = require('firebase-admin');
      
      // INIT
      admin.initializeApp();
      
      // LISTEN TO UPDATES
      exports.onItemDocumentUpdate = functions.firestore.document('test1/{test1ID}').onUpdate(async (change, context) => {
          // GETS PARAMS
          const currentTest1ID = context.params.test1ID
      
          // READ THE COLLECTION
          const currentTest2DocumentList = await admin.firestore().collection('test1/' + currentTest1ID + '/test2').get().then(function(collectionSnapShot) {
              return collectionSnapShot.docs.map(function (doc){
                  return doc.data();
              })
          })
      
          // GETS THE SUM USING THE REDUCE METHOD.
          const addedValue = currentTest2DocumentList.reduce((x,y)=>{
              return x + y.field1;
          }, 0);
      
          // UPDATES TEST.
          return admin.firestore().collection('test1').doc(currentTest1ID).update({testField: 
              addedValue
          });
      })
      

      我还可以建议在我的回答中使用像so 这样的递增和递减解决方案来减少文档读取吗?它会为您节省很多每月的账单。

      【讨论】:

        猜你喜欢
        • 2021-02-24
        • 1970-01-01
        • 2018-03-23
        • 1970-01-01
        • 2021-12-26
        • 2021-08-02
        • 2018-03-27
        • 2021-11-09
        • 2021-10-06
        相关资源
        最近更新 更多