[英]Firestore cloud function to recursively update subcollection/collectionGroup
[英]Firestore update function not working with collectionGroup
我正在尝试更新 Firestore 中的文档,但是当我不使用 collectionGroup 而是通过 id 获取文档时,我得到“未处理的错误 TypeError:res.docs[0].update 不是函数更新 function 工作正常。 这是我的代码:
await db.collectionGroup('campaigns').where('campaignId', '==', data.campaignId).get()
.then((res: any) => {
res.docs[0].update({status: data.status}).then((result: any) => {
return {success: true}
},(err: any) => {
return {success: err};
});
return {success: true};
QuerySnapshot
中的docs
集合包含DocumentSnapshot
对象。 为了能够调用update()
你需要有一个DocumentReference
。 要从文档快照获取参考,请在其上调用ref
。
所以:
res.docs[0].ref.update(...)
您的问题最终源于文档和许多博客文章不鼓励在您的类型中使用any
类型。 它有效地“关闭”TypeScript,然后您也可以使用普通的 JavaScript。 您还应该避免调用变量res
或result
,而是将它们称为更接近它们的内容,例如DocumentSnapshot
的doc
或querySnapshot
的QuerySnapshot
。
Firebase SDK 导出它们的所有类型,您的then()
处理程序中的res
将自动获得QuerySnapshot<DocumentData>
类型,并且在您使用update()
的地方会显示错误。
res.docs[0]
将是一个QueryDocumentSnapshot
(当你有结果时),它没有update()
function。 要访问本文档的update()
,您需要它的参考,可以使用res.docs[0].ref
。
所以要修复
res.docs[0].update({status: data.status})
你会把它改成
res.docs[0].ref.update({status: data.status})
但是,在您当前的代码中,您也没有正确链接承诺,这意味着您的错误将无法正确处理。
await db.collectionGroup('campaigns').where('campaignId', '==', data.campaignId).get()
.then((res: any) => {
/* need return here */ res.docs[0].update({status: data.status}).then((result: any) => {
return {success: true}
}, (err: any) => {
return {success: err};
});
return {success: true}; // instead of here
});
您可以通过重新排列代码来帮助解决这些类型的问题:
await db.collectionGroup('campaigns')
.where('campaignId', '==', data.campaignId)
.limit(1) // if you are only using 1 result anyway, may as well request just 1.
.get()
.then((qSnapshot) => {
return qSnapshot.docs[0].ref
.update({ status: data.status })
})
.then(
() => {
return { success: true }
},
(err) => {
return { success: err }
}
);
在考虑如何重写行以提高可读性时,请考虑以下结构:
starterLocation // firebase.firestore() or db.collection("someCollection") or someRef (a variable containing a Reference object)
.child() // this would be as many .collection() or .doc() as needed
.child()
.filter() // this would be as many .orderBy(), .where(), .startAt(), etc as needed
.filter()
.operation() // this would be get() or onSnapshot() for queries,
// or set(), update(), delete() for references
然后,您将使用传统的Promise 链(记得检查您的回报!)或您想要的更新的async
/ await
语法来处理它的结果。
以上面的代码为例:
await db.collectionGroup('campaigns') // the starter location
.where('campaignId', '==', data.campaignId) // a filter
.limit(1) // another filter
.get() // the operation
.then((qSnapshot) => {
return qSnapshot.docs[0].ref // the starter location
.update({ status: data.status }) // the operation
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.