Firebase 交易是否可用于托收?

Firebase 交易是否可用于托收?,firebase,transactions,google-cloud-platform,flutter,google-cloud-firestore,Firebase,Transactions,Google Cloud Platform,Flutter,Google Cloud Firestore,我正在使用Firestore,并尝试通过使用事务删除Flatter应用程序中的竞态条件 我有子集合,其中最多添加2个文档 竞争条件意味着可能会添加2个以上的文档,因为客户端代码是usesetData。例如: Firestore.instance.collection(‘collection').document('document').collection('subCollection’).document(subCollectionDocument2).setData({ ‘documen

我正在使用Firestore,并尝试通过使用事务删除Flatter应用程序中的竞态条件

我有子集合,其中最多添加2个文档

竞争条件意味着可能会添加2个以上的文档,因为客户端代码是use
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”

事务是否可用于监视对子集合的更改

有人知道其他解决办法吗

事务是否可用于监视对子集合的更改

Firestore中的事务由所谓的。在事务中,您从数据库读取文档,确定其当前状态,然后根据该状态设置其新状态。当您对整个事务执行此操作时,您将当前状态和新状态文档的整个包发送到服务器。然后,服务器检查存储层中的当前状态是否仍然与客户端启动时的状态匹配,如果匹配,则提交您指定的新状态

知道了这一点,监控事务中整个集合的唯一方法是将该集合中的所有文档读入事务中。虽然这在技术上对小型收藏是可行的,但它的效率可能非常低,而且我在实践中从未见过这样做。同样,对于您的收藏中的两个文档,在事务中简单地读取它们可能是完全可行的


请记住,尽管事务只确保数据的一致性,但它并不一定限制恶意用户的行为。如果要确保集合中的文档不会超过两个,则应查看服务器端机制

最简单的机制(基础设施方面)是使用Firestore的服务器端安全规则,但我认为这些规则无法限制集合中的文档数量,Doug在回答问题时解释了这一点


在这种情况下,最有可能的解决方案是(正如Doug所建议的)使用云函数在子集合中编写文档。这样,您就可以简单地拒绝来自客户端的直接写入,并在您的云函数代码中强制执行您想要的任何业务逻辑,该代码在可信环境中运行。

谢谢您的回复!但我不知道云函数如何阻止竞争条件。正如道格所解释的,它们不能同步工作。但它们在可信的环境中运行,因此您可以编写代码以确保遵守业务规则。例如:1)加载集合中的所有文档,2)对它们进行计数,3a)如果多于2个,则发回错误,3b)如果少于2个,则从用户处写入文档。谢谢。我现在正在尝试测试这个。但在理论上,我仍然认为会有超过2个文件可能在收集的结果。因为如果2个功能实例同时运行,并且对集合中的单据进行计数,则只能看到1个单据。然后他们都会写信给集合。所以,问题在于收集(步骤2)中的文档计数和写入(步骤3)之间的时间差。我是对的?这就是交易的意义所在。您仍然可以在服务器端代码中使用事务,您可以保证这是编写这些文档的唯一方法。谢谢!但你说监控整个收集非常低效?