我试图用firebase创建一个协作编辑器,为此,我排队发送更新到文件的操作列表(类似于https://www.youtube.com/watch?v=LEoWPdQh27c中所描述的)。
我通过事务发送操作,类似于文件中描述的操作,如下所示:
Future<void> sendOperations(List<SyncedOperationMixin> operations) async {
var currentStep = this.currentStepIndex;
return firestore.runTransaction(
(transaction) async {
final currentStepDoc = stepsReference.doc(getStepDocumentName(currentStep + 1));
// If the document with the next-most step id exists, we need to rebase (throw an error)
// otherwise, upload the operations
},
maxAttempts: 1,
timeout: const Duration(seconds: 2),
).then((r) {
this.currentStepIndex = currentStep;
});
然后我有一个循环,它发送操作并等待sendOperation调用,如果它们失败需要一个rebase,它会调度一个rebase,否则如果抛出任何其他错误,它会在延迟后重试。
如果连接不存在的话,我本以为firebase会在[timeout]之后失败,并出现某种错误,但它似乎会缓存事务,并在网络再次在线时运行它。
这对我来说不起作用,原因有很多,比如:
- 如果一个批处理的操作由于连接错误而发送失败,我可以将它们与下一个批处理一起发送(如果firestore缓存该操作,则该操作不会工作,因为它们从未失败)
- 缓存意味着它们引用旧的数据,例如旧的stepIndexes
- 如果连接长时间处于关闭状态(因为其他用户可能在此期间进行了编辑),则重新应用它们时总是会失败
有没有一种方法可以告诉firebase不要排队/缓存操作,而是在连接断开时使它们失败?
(在本例中,我使用的是flutter API)
1条答案
按热度按时间w1jd8yoj1#
从transactions的文档中:
当客户端脱机时,事务将失败。
所以如果你的事务在一定时间后没有失败(可能是
maxAttempts x timeout
),这意味着它没有按照它的文档工作,你可能应该为它提交一个bug。但是在你分享的代码中,我根本没有看到你与
transaction
交互,所以这可能解释了为什么没有失败。我试着重现问题here,代码如下:
如果我在运行之前断开网络,我会收到错误消息,指示缺乏网络连接:
[11:21:41]这通常表示您的设备目前没有正常的互联网连接。客户端将在脱机模式下运行,直到它能够成功连接到后端。
[11:21:41] Firestore(9.18.0):无法访问Cloud Firestore后端。连接失败% 1次。最新错误:FirebaseError:[代码=不可用]:无法完成该操作
[11:21:41] [2023-09-20T09:21:41.481Z] @firebase/firestore:
[11:21:41] [object对象]
[11:21:41] RPC“侦听”流0x 1d 862 c69传输错误:
[11:21:41] Firestore(9.18.0):网站Map
[11:21:41] [2023-09-20T09:21:41.480Z] @firebase/firestore:
[11:21:42]运行事务时出错:[cloud_firestore/unavailable]连接失败。
如果我随后重新建立网络连接,则交易不会**完成。这是预期的行为,给定调用中指定的超时值。