Firestore交易失败,并显示“交易失败所有重试”

时间:2018-06-21 19:08:10

标签: firebase transactions google-cloud-firestore flutter

我正在运行一个非常简单的Firestore事务,该事务将检查文档是否存在,如果不存在则先将其写入。

(用例正在注册用户名-如果尚未注册,则当前用户可以获取它)

以下是相关的Flutter代码的片段:

DocumentReference usernameDocRef =
    Firestore.instance.collection(_USERNAMES).document(username);

await Firestore.instance.runTransaction((transaction) async {
  var snapshot = await transaction.get(usernameDocRef);
  if (!snapshot.exists) {
    transaction.set(usernameDocRef, {
      _UsernamesKey.userid: _user.id,
    });
  }
});

此操作失败,但出现异常“事务重试所有重试失败”。

基于Firestore documentation,失败的发生可能有两个原因:

  
      
  • 事务在写操作之后包含读操作。读取操作必须始终在任何写入操作之前进行。
  •   
  • 该事务读取了在事务外部修改的文档。在这种情况下,事务将自动再次运行。该交易被重试了有限次。
  •   

我认为我不会触发任何一个。有什么建议吗?

4 个答案:

答案 0 :(得分:0)

example transaction in the documentation在调用await时使用update。也许您在呼叫set时也需要这样做:

await Firestore.instance.runTransaction((transaction) async {
  var snapshot = await transaction.get(usernameDocRef);
  if (!snapshot.exists) {
    await transaction.set(usernameDocRef, {
      _UsernamesKey.userid: _user.id,
    });
  }
});

答案 1 :(得分:0)

首先,尝试使用原始快照中的引用,而使用原始文档引用中的。如果这不起作用,请尝试将[设置]更改为[更新],因为我记得与您现在遇到的错误相同。

DocumentReference usernameDocRef =
        Firestore.instance.collection(_USERNAMES).document(username);

await Firestore.instance.runTransaction((transaction) async {
  var snapshot = await transaction.get(usernameDocRef);
  if (!snapshot.exists) {
    await transaction.update(snapshot.reference, {
      _UsernamesKey.userid: _user.id,
    });
  }
});

答案 2 :(得分:0)

最近已修复-https://github.com/flutter/plugins/pull/1206

如果您使用的是master channel,则此修复程序应该已经可用。对于其他渠道(开发,测试版,稳定版)YMMV。

答案 3 :(得分:-1)

我不是Flutter / Dart专家,但我希望您必须从交易中返回某些信息,以便Firestore知道何时完成:

await Firestore.instance.runTransaction((transaction) async {
  var snapshot = await transaction.get(usernameDocRef);
  if (!snapshot.exists) {
    return transaction.set(usernameDocRef, {
      _UsernamesKey.userid: _user.id,
    });
  }
})