在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
});
}
});
答案 0 :(得分:1)
您将必须确保仅在执行所有更新之后调用batch.commit()
。您的代码现在正在做的工作是在调用第二个更新之前提交。
问题在于get()
是异步的,并且在查询完成之前立即返回。如果添加一些日志记录语句,您将更好地了解正在发生的事情。您需要做的是,等到从get()返回的promise完全解析后再提交批处理。这意味着您对batch.commit()
的调用可能应该出现在then
回调中。
答案 1 :(得分:0)
您对batch.update(refNo, { [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);
});