Javascript 获取文档时出错:clientDetails错误:无法修改已提交的写回
在Firestore批量更新中出现此错误的原因是什么?承诺作为批提交返回,批在循环中创建。我无法理解这个问题。有什么建议吗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
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);
});