【问题标题】:How can I write to the Realtime Database, Cloud Storage and Firestore at the same time using transactions?如何使用事务同时写入实时数据库、云存储和 Firestore?
【发布时间】:2023-01-12 18:43:52
【问题描述】:
我正在用 Flutter 开发一个应用程序,我有一个名为 **CreateUser ** 的方法,它将用户信息、他的个人资料图片和字符串列表作为参数,我需要将这些信息保存在实时数据库中,图片在 Cloud Storage 中和 Firestore 中的列表。
我希望所有这些操作都能成功,如果其中一个操作失败,那么我希望其他人撤消他们写入的数据。如何实现其他操作的回滚?我可以使用交易吗?
我试过使用事务,但我不确定我是否可以在不同的数据库上使用它们。
【问题讨论】:
标签:
firebase
google-cloud-platform
firebase-realtime-database
google-cloud-firestore
firebase-storage
【解决方案1】:
我需要把信息存到Realtime Database,图片存到Cloud Storage,列表存到Firestore。
这确实是可能的。如何?仅当操作成功时才执行一个操作。例如,一旦将数据写入 Realtime Database 的操作完成,然后在回调中,执行将图像添加到 Storage。一旦将图像添加到 Storage 成功,就执行最后一个将数据写入 Firestore 的操作。
我希望所有这些操作都能成功,如果其中一个操作失败,那么我希望其他人撤消他们写入的数据。
没有内置的机制。如果您认为可以添加批处理操作、实时数据库写入操作、Firebase 存储文件上传
和 Firestore 的写操作,并确保三者都完整,这样你才能有一致的数据,请注意,这是不可能的。这些操作是不同 Firebase 服务的一部分,不幸的是,目前我正在写这个答案,您无法使它们成为原子操作,这意味着全部成功或全部失败并出现异常。
如何实现其他操作的回滚?
您必须为此编写代码,因为没有任何 Firebase 产品支持跨产品事务操作。要解决这个问题,您必须在写入/上传操作期间嵌套调用,并在下一次操作失败时处理错误。这意味着如果 Firestore 中的写入操作失败,您要么必须从实时数据库中删除数据,要么从存储中删除文件。或者仅在文件上传到存储失败时从实时数据库中删除数据。
但是请注意,在某个时间点,会出现客户端无法回滚其中一个删除操作的故障。考虑到第一个操作是将数据写入实时数据库的操作,对于可能发生的这些不可避免的故障,最常见的方法是通过在 Firebase 存储和 Firestore 两个地方处理异常和执行偶尔的清理来使您的代码健壮。
正如与 Firebase 工程师讨论的那样,原因很清楚。即使Realtime Database和Cloud Firestore都是Firebase的产品,它们仍然是不同的产品。除此之外,Firebase Storage 是 Google Cloud 中的一项服务。所以现在,2023 年 1 月 12 日,我们无法做到这一点。希望它在不久的将来可用。
我可以使用交易吗?
不,那是出于与上述完全相同的原因。