我正在使用Firestore,并尝试通过使用事务删除Flutter应用中的竞争条件。
我有一个子集合,最多可以添加2个文档。
种族条件意味着可能会添加两个以上的文档,因为客户端代码使用的是setData
。例如:
Firestore.instance.collection(‘collection').document('document').collection('subCollection’).document(subCollectionDocument2).setData({
‘document2’: documentName,
});
我正在尝试使用事务来确保最多添加2个文档。因此,如果在事务运行期间更改了收集(例如将新文档添加到收集中),则事务将失败。
但是我读过文档,并且看来交易更多地用于竞争条件,即在文档中设置字段,而不是在子集合中添加文档。
例如,如果尝试实施:
Firestore.instance.collection(‘collection').document('document').collection('subCollection').runTransaction((transaction) async {
}),
给出错误:
错误:未为类“ CollectionReference”定义方法“ runTransaction”。
事务可以用于监视子集合更改吗?
有人知道其他解决方案吗?
答案 0 :(得分:0)
事务可以用于监视子集合更改吗?
Firestore中的事务通过所谓的compare-and-swap operation工作。在事务中,您从数据库中读取文档,确定其当前状态,然后基于该状态设置其新状态。完成整个事务后,您会将整个当前状态和新状态文档包发送到服务器。然后,服务器检查存储层中的当前状态是否仍然与客户端开始时的状态匹配,如果是,它将提交您指定的新状态。
认识到这一点,监视事务中整个集合的唯一方法就是将该集合中的所有文档读入事务中。虽然从技术上讲,对于小型收藏品来说这是可行的,但效率可能很低,而且我从未在实践中见过它。再说一次,对于您集合中的两个文档,在事务中简单地读取它们可能是完全可行的。
请记住,尽管交易仅确保一致的数据,但不一定限制恶意用户的操作。如果要确保集合中的文档数量不超过两个,则应查看服务器端机制。
最简单的机制(从基础架构角度出发)是使用Firestore的服务器端安全规则,但是我不认为这些规则会限制集合中文档的数量,如Doug在他对{{3}的回答中所解释的那样。 }。
在这种情况下,最可能的解决方案是(如Doug所建议的)使用Cloud Functions将文档写入子集合中。这样,您可以简单地拒绝来自客户端的直接写操作,并在需要在受信任环境中运行的Cloud Functions代码中实施所需的任何业务逻辑。