当 (document.exist) 不为 true 时,else 语句不起作用"firestore"



我想循环抛出一个对象数组,并检查每个对象中的数据是否存在于数据库中,然后如果数据存在则执行一个特定的任务,如果数据不存在则执行另一个任务。但是,如果数据库中没有数据,并且代码停在if语句之前的行,则不会执行else语句。注意:当document.exists为真时,if语句工作正常,只有当数据不存在时才会出现问题。

result_array.forEach((doc)=>{
console.log(doc.id)
db.collection("users").doc(auth.user.uid).collection("basket").where( "id" , "==" ,doc.id ).get()
.then((docs) => {
docs.forEach(document=>{
if (document.exists) {
console.log("Document data:", document.data());
document.ref.update({
"quantity": document.data().quantity + doc.quantity,
})
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
db.collection("users").doc(auth.user.uid).collection("basket").add({
id: doc.id,
quantity: doc.quantity
})
}
})          
})
})

查询返回的文档与您的条件完全匹配,这意味着QuerySnapshot中返回的所有文档都存在。forEach循环中的if (document.exists)检查是多余的。

您是否检查是否至少有一个文档匹配您的查询?

尝试在QuerySnapshot上使用.empty属性来检查查询是否返回了任何文档:

db.collection("users").doc(auth.user.uid).collection("basket").where( "id" , "==" ,doc.id ).get()
.then((docs) => {
if (docs.empty) {
// console.log("0 documents returned")
} else {
// Docs returned 
console.log(docs.docs.map(d => d.data()))
}
})

虽然@Dharmaraj的答案解决了您的直接查询,但通过调整存储购物篮的方式,您可以消除查询并消除购物篮中重复项目的可能性。

下面的答案假设result_array(下面重命名为items_array)是要添加到用户购物篮中的商品数组,/users/someUserID/basket是用户当前购物篮。

您可以通过使用项目的ID作为文档的键来简化代码。这将涉及切换出以下代码:

db
.collection("users")
.doc(auth.user.uid)
.collection("basket")
.add({
id: item.id,
quantity: item.quantity
});

:

db
.collection("users")
.doc(auth.user.uid)
.collection("basket")
.doc(item.id) // <- use the item ID as the document ID
.set({
id: item.id, // <- you could remove this if desired
quantity: item.quantity
});

通过使用increment()操作,您可以将数量增加到请求的数量。我使用set(){ merge: true },你可以创建文档,如果它不存在或更新现有的数量,如果它存在,在一个单一的操作:

db
.collection("users")
.doc(auth.user.uid)
.collection("basket")
.doc(item.id) // <- use the item ID as the document ID
.set({
id: item.id, // <- you could remove this if desired
quantity: firebase.firestore.FieldValue.increment(item.quantity)
}, { merge: true }); // <- creates/updates document

你还可以进一步优化你的代码,把对篮子的引用从for循环中取出来。

const userBasketColRef = db
.collection("users")
.doc(auth.user.uid)
.collection("basket");
items_array.forEach(item => {
userBasketColRef
.doc(item.id) 
.set({
id: item.id,
quantity: firebase.firestore.FieldValue.increment(item.quantity)
}, { merge: true })
.catch(err => {
// don't forget error handling!
console.error('Failed to update basket for item #' + item.id, err);
});
});

最后,您可以切换到使用批处理写入来一次(自动地)进行所有更改,并在一个位置处理错误:

const batch = db.batch();
const userBasketColRef = db
.collection("users")
.doc(auth.user.uid)
.collection("basket");
items_array.forEach(item => {
batch.set(
userBasketColRef.doc(item.id), // <- use the item ID as the document ID
{
id: item.id,
quantity: firebase.firestore.FieldValue.increment(item.quantity)
},
{ merge: true }
);
});
batch.commit()
.then(() => console.log('Updated basket successfully!'))
.catch((err) => console.error('Failed to update basket'));

最新更新