我正在尝试更新同一文档,该文档触发了onupdate云功能,并从同一集合中具有读取值。这是一种在flutter中制作的聊天应用程序中,以前对查询的响应已复制到现在已更新的文档,以便于在应用中显示。
代码确实有效,但是当用户快速响应两个单独的查询时,他们都读取相同的最新响应,从而设置了相同的先前响应。这必须归结为颤动和/或云功能的异步性质,但是我无法弄清楚在哪里等待或是否有更好的方法来制作该函数,因此它永远不会触发同一用户的Update,直到先前的触发器完成。最后一部分听起来有点像一个坏主意。
到目前为止,我尝试将读/更新粘贴在交易中,但是这似乎仅适用于单个功能调用,而在它们异步时也不适用。还认为我可以通过阅读客户端交易中的先前响应,但是Firebase在不使用服务器API时不允许从集合中阅读。
时。async function setPreviousResponseToInquiry(
senderUid: string,
recipientUid: string,
inquiryId: string) {
return admin.firestore().collection('/inquiries')
.where('recipientUid', '==', recipientUid)
.where('senderUid', '==', senderUid)
.where('responded', '==', true)
.orderBy('modified', 'desc')
.limit(2)
.get().then(snapshot => {
if (!snapshot.empty &&
snapshot.docs.length >= 2) {
return admin.firestore()
.doc(`/inquiries/${inquiryId}`)
.get().then(snap => {
return snap.ref.update({
previousResponse: snapshot.docs[1].data().response
})
})
}
})
}
我看到了三个可能的解决方案:
- 使用服务器上的事务,该交易确保您编写的更新必须基于您读取的数据的版本。如果您编写的值取决于触发云功能的数据,则可能需要重新阅读该数据作为事务的一部分。
- 不要使用云功能,而是从客户端运行所有更新。这使您可以使用交易来防止比赛条件。
- 如果不可能使用事务,则可能必须在上游数据(触发写入的数据(中包括自定义版本编号,以及您正在更新的封口数据。然后,您可以使用安全规则来确保仅当其版本与当前上游数据匹配时才能编写下游数据。
我会考虑/尝试以上顺序,因为它们逐渐参与。