【问题标题】:How to properly chain futures with firebase transaction on flutter?如何在颤振上正确链接期货与火力交易?
【发布时间】:2018-11-15 08:14:14
【问题描述】:

这是我的代码。成功返回false,因为文档长度为0。

   var sucess = await Firestore.instance.runTransaction((transaction) async {
      await transaction.set(userReference, userMap);
    }).then((_) {
      return Firestore.instance.collection(CollectionName.user).where(FirebaseUserField.uid, isEqualTo: userMap["uid"]).getDocuments();
    }).then((querySnapshot) {
      if (querySnapshot.documents.length == 0) {
        return false;
      }
      return true;
    }).catchError((e) {
      print(e);
      return false;
    });

这段代码进入我的第二个未来,我在数据库中查询我刚刚使用先前事务更新的用户。 我想将所有内容与期货链接起来,以简化错误检查。

从 Firestore 文档中,我可以看到处理程序解析为事务的返回值,但调用事务的实例解析为空映射。

runTransaction((Transaction) → Future<dynamic> transactionHandler, {Duration timeout: const Duration(seconds: 5)}) → Future<Map<String, dynamic>>

事务完成后调用下一个future的正确方法是什么,或者如果失败则进入错误。

需要考虑的一点是,当我使用查询用户的断点进行调试时,会出现延迟,但我会正确获取用户。

用户也已正确写入我的数据库。

编辑:我也试过了

var sucess = await Firestore.instance.runTransaction((transaction) async {
      return transaction.set(userReference, userMap);
    })

但是没有用。

【问题讨论】:

    标签: firebase google-cloud-firestore flutter


    【解决方案1】:

    我认为这与您的事务中嵌套的 await 有关,这也可以解释您在调试期间看到的竞争条件。

    当您在runTransaction 中使用此事务处理程序时会发生什么?

    (transaction) {
      return transaction.set(userReference, userMap);
    }
    

    【讨论】:

    • 一样,已经试过了。经过一番思考,似乎竞争条件与firebase服务器有关,事务在客户端结束,并立即开始新的请求以获取文档,但firebase服务器也需要时间来处理事务。这只是我现在的猜测。
    • 我刚看了文档,事务完成后,确定,写入数据。
    • 您是否尝试过不使事务处理程序异步而只返回transaction.set?在您的编辑中,处理程序仍然是异步的。
    • 没有尝试过,但据我从文档中记得,异步函数不再作为微交易产生
    • 我会努力做到的
    【解决方案2】:

    您将 Future 与 await 混为一谈。尝试删除Firestore.instance.runTransaction之前的第一个等待

    var sucess = Firestore.instance.runTransaction((transaction) async {
          await transaction.set(userReference, userMap);
        }).then((_) {
          return Firestore.instance.collection(CollectionName.user).where(FirebaseUserField.uid, isEqualTo: userMap["uid"]).getDocuments();
        }).then((querySnapshot) {
          if (querySnapshot.documents.length == 0) {
            return false;
          }
          return true;
        }).catchError((e) {
          print(e);
          return false;
        });
    

    您可能还需要从 await transaction.set(userReference, userMap); 中删除 await,因为它会立即返回,但不是 100% 确定

    【讨论】:

      猜你喜欢
      • 2023-03-22
      • 2021-06-05
      • 2019-05-31
      • 2018-07-09
      • 2021-03-10
      • 2021-07-03
      • 2021-11-20
      • 2020-11-04
      • 2020-09-07
      相关资源
      最近更新 更多