我想循环抛出一个对象数组,并检查每个对象中的数据是否存在于数据库中,然后如果数据存在则执行一个特定的任务,如果数据不存在则执行另一个任务。但是,如果数据库中没有数据,并且代码停在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'));