Javascript 获取文档时出错:clientDetails错误:无法修改已提交的写回

Javascript 获取文档时出错:clientDetails错误:无法修改已提交的写回,javascript,firebase,google-cloud-firestore,google-cloud-functions,updates,Javascript,Firebase,Google Cloud Firestore,Google Cloud Functions,Updates,在Firestore批量更新中出现此错误的原因是什么?承诺作为批提交返回,批在循环中创建。我无法理解这个问题。有什么建议吗 export const updateUserDetailsTypeform = functions.firestore. document('responseClientDetails/{case}').onCreate((snap, context) => { const newValue = snap.data(); const caseR

在Firestore批量更新中出现此错误的原因是什么?承诺作为批提交返回,批在循环中创建。我无法理解这个问题。有什么建议吗

export const updateUserDetailsTypeform = functions.firestore.
  document('responseClientDetails/{case}').onCreate((snap, context) => {

    const newValue = snap.data();
    const caseReference = snap.id;
    var batch = db.batch();

    var reg = "[^£]*£[^£]*";
    const uid = caseReference.match(reg);
    if (uid && newValue) {

      let document = db.collection("responseClientDetails").doc(caseReference);
      let refDoc = db.collection("clientDetails").doc(uid[0])
      batch.update(refDoc,{ has_seen_setup: "true" })


 document.get().then(function (doc: any) {
        if (doc.exists) {
          let refNo = db.collection("clientDetails").doc(uid[0])
          for (let [key, value] of Object.entries(doc.data())) {
            const keyValue = key;
            const valueValue = value;
            batch.update(refNo, { [keyValue]: valueValue })
           // promises.push(db.collection("clientDetails").doc(uid[0]).update({ [keyValue]: valueValue }))
          }

        }else{
          console.log("document does not exist")
        } 
      }).catch(function (error: any) {
        console.log("Error getting document: clientDetails", error);
      });



return batch.commit().then(function () {
  console.log("updated clientDetails")
  return null

});

    }


  });



您必须确保仅在执行所有更新后才调用batch.commit。您的代码现在所做的是在调用第二次更新之前提交

问题在于get是异步的,并且在查询完成之前立即返回。如果添加一些日志记录语句,您将更好地了解发生了什么。相反,您需要做的是等待get返回的承诺完全解决后再提交批处理。这意味着您对batch.commit的调用可能会出现在then回调中。

您对batch.updaterefNo的调用,{[keyValue]:valueValue}异步运行,并在您对batch.commit的调用后触发

让我们稍微整理一下您的代码示例,并添加一些注释来帮助说明发生了什么

// 1 - This fires synchronously
batch.update(db.collection("clientDetails").doc(uid[0]), { has_seen_setup: "true" });

// 2 - This fires synchronously
db.collection("responseClientDetails").doc(caseReference).get().then(function (doc: any) {
  if (doc.exists) {
    let refNo = db.collection("clientDetails").doc(uid[0])
    for (let [key, value] of Object.entries(doc.data())) {
      const keyValue = key;
      const valueValue = value;
      // 4 - This fires asynchronously AFTER #3 runs, therefore the batch has been committed
      batch.update(refNo, { [keyValue]: valueValue })
    }
  } else {
    console.log("document does not exist")
  }
}).catch(function (error: any) {
  console.log("Error getting document: clientDetails", error);
});

// 3 - This fires synchronously
return batch.commit().then(function () {
  console.log("updated clientDetails")
  return null
});
因此,您的解决方案可能是将batch.commit调用移动到then调用中:

batch.update(db.collection("clientDetails").doc(uid[0]), { has_seen_setup: "true" });

db.collection("responseClientDetails").doc(caseReference).get().then(function (doc: any) {
  if (doc.exists) {
    let refNo = db.collection("clientDetails").doc(uid[0])
    for (let [key, value] of Object.entries(doc.data())) {
      const keyValue = key;
      const valueValue = value;
      batch.update(refNo, { [keyValue]: valueValue })
    }
  } else {
    console.log("document does not exist")
  }
})
.then(() => {
  return batch.commit().then(function () {
    console.log("updated clientDetails")
    return null
  });
})
.catch(function (error: any) {
  console.log("Error getting document: clientDetails", error);
});