如何使用事务同时写入实时数据库、云存储和Firestore ?



我正在开发一个应用程序在Flutter,我有一个名为**CreateUser **的方法,它以参数的用户信息,他的个人资料图片,和字符串列表,我需要保存在实时数据库中的信息,在云存储中的图片和在Firestore中的列表。

我希望所有这些操作都成功,如果其中一个操作失败,那么我希望其他操作撤销它们写的数据。如何实现其他操作的回滚?我可以使用事务吗?

我试过使用事务,但我不确定我是否可以在不同的数据库上使用它们。

我需要在实时数据库中保存信息,在云存储中保存图片,在Firestore中保存列表。

通过一个操作接一个操作,只有当操作成功时才执行操作,这确实是可能的。例如,一旦将数据写入Realtime Database的操作完成,那么在回调中,执行将图像添加到Storage的操作。一旦映像添加到Storage成功,执行最后一个操作——将数据写入Firestore。

我希望所有这些操作都成功,如果其中一个操作失败,那么我希望其他操作撤销它们写的数据。

没有这样的内置机制。如果你认为你可以添加一个批处理操作,一个实时数据库写操作,一个Firebase存储文件上传和Firestore写操作并确保这三个都完成,这样就可以有一致的数据,请注意这是不可能的。这些操作是不同Firebase服务的一部分,不幸的是,在我写这个答案的时候,你没有办法让它们原子化,这意味着所有成功或所有失败都有一个异常。

如何实现其他操作的回滚?

你必须为此编写代码,因为没有Firebase产品支持跨产品事务操作。要解决这个问题,必须在写/上传操作期间嵌套调用,并在下一个操作失败时处理错误。这意味着如果在Firestore中写入操作失败,您要么必须从实时数据库中删除数据,要么必须从存储中删除文件。或者只在文件上传到存储失败时从实时数据库中删除数据。

但是请注意,在某个时间点,会出现客户端无法回滚其中一个删除操作的失败。对于这些可能发生的不可避免的失败,最常见的方法是通过处理异常和在Firebase Storage和Firestore两个地方执行偶尔的清理来使你的代码健壮,考虑到第一个操作是向实时数据库写入数据。

与Firebase工程师讨论过,原因很清楚。即使Realtime Database和Cloud Firestore都是Firebase产品,它们仍然是不同的产品。除此之外,Firebase Storage是Google Cloud中的一项服务。所以现在,2023-01-12我们不可能做到这一点。希望它能在不久的将来可用。

我可以使用事务吗?

不,这和上面的原因完全一样。

我可能解决这个问题的一种方法是使用Firestore文档写入操作来触发一个Workflow[1],它可以处理这三个操作并根据故障状态进行回滚。这样,您还可以在流程中保持恒定的事务记录。

如果你想向用户提供应用程序反馈,你可以让你的应用程序等待完成(或错误)的DB记录被写入,并基于该报告返回给用户。

[1] https://cloud.google.com/firestore/docs/solutions/workflows

最新更新