【问题标题】:Transaction Firestore Not Executing事务 Firestore 未执行
【发布时间】:2022-01-12 15:59:33
【问题描述】:

我在通过事务写入 Firestore 时遇到了一些问题。我正在尝试通过将 otherUserID 添加到用户的文档数组中来更新属于用户的集合中的所有文档。用户的文档数组没有更新,经过一些调试,我发现问题是“断点 2”下面的代码在“断点 1”之前执行,这意味着事务更新永远不会发生,因为 dataList 仍然是空的。

但是从代码的编写方式来看,forEach中的代码不应该先完成“断点1”吗?

Future<void> updateData(User myUser, String otherUserID) async {
  List<Data> dataList = [];
  QuerySnapshot<Map<String, dynamic>> otherDataQuery =
      await FirebaseFirestore.instance
          .collection('data')
             .where('userID', isEqualTo: myUser.userID)
          .get();
  await FirebaseFirestore.instance.runTransaction(
    (transaction) async {
      otherDataQuery.docs.forEach(
        (document) async {
          Data oldData = Data.fromMap(
            document.data(),
          );
          DocumentSnapshot snapshot = await transaction.get(
            dataRef.doc(oldData.ID),
          );
          Data thisData =
              Data.fromMap(snapshot.data() as Map<String, dynamic>);
          thisData.users!.add(otherUserID);
          dataList.add(thisData);
          print('Breakpoint 1');
          print(dataList.length);
        },
      );
      print('Breakpoint 2');
      print(dataList.length);
      for (var i = 0; i <= dataList.length - 1; i++) {
        await transaction.update(
          dataRef.doc(dataList[i].ID),
          {'usersList': dataList[i].users},
        );
      }
    },
    timeout: Duration(seconds: 10),
  );
}

【问题讨论】:

    标签: flutter google-cloud-firestore


    【解决方案1】:

    forEach 循环替换为for 循环。

    async forEach 与 async for 循环有点不同

    otherDataQuery.docs.forEach(
      (document) async {
        Data oldData = Data.fromMap(document.data());
        print('TEST 1');
        DocumentSnapshot snapshot = await transaction.get(
          dataRef.doc(oldData.ID),
        );
        print('TEST 2');
        Data thisData = Data.fromMap(snapshot.data() as Map<String, dynamic>);
        thisData.users!.add(otherUserID);
        dataList.add(thisData);
        // print('Breakpoint 1');
        // print(dataList.length);
      },
    );
    print('TEST 3');
    // for (var i = 0; i <= dataList.length - 1; i++) { ... }
    

    假设 otherDataQuery 包含 3 个文档,上面的函数应该打印如下。

    TEST 1
    TEST 1
    TEST 1
    TEST 3
    TEST 2
    TEST 2
    TEST 2
    

    因此,测试 3(您的 for 循环)将在测试 2 (transaction.get()) 完成之前被调用。因此,print(dataList.length) 将打印0。所以改为使用for 循环。

    所以,试试这个:

    for (int i = 0; i < otherDataQuery.size; i++) {
      Data oldData = Data.fromMap(otherDataQuery.docs[i].data());
      DocumentSnapshot snapshot = await transaction.get(
        dataRef.doc(oldData.ID),
      );
      Data thisData = Data.fromMap(snapshot.data() as Map<String, dynamic>);
      thisData.users.add(otherUserID);
      dataList.add(thisData);
      print('Breakpoint 1');
      print(dataList.length);
    }
    

    【讨论】:

    • 谢谢彼得!我会跟进,看看我的情况是否顺利。
    猜你喜欢
    • 2015-11-15
    • 1970-01-01
    • 2021-09-28
    • 2018-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多