【问题标题】:How to get sub-collections of every collection in Firestore using Flutter如何使用 Flutter 获取 Firestore 中每个集合的子集合
【发布时间】:2020-12-28 08:38:45
【问题描述】:

我正在构建一个任务管理应用程序,其中每个用户都有多个项目(集合),每个项目内部都有任务(集合),每个任务内部都有子任务。

我能够使用此代码检索所有项目:

User user = Provider.of<User>(context);
CollectionReference projects = Firestore.instance.collection('users').document(user.uid).collection("projects");

但我的问题是如何从每个项目中获取所有任务和子任务(如果存在)并将它们列出在 StreamBuilder 中?

这是我当前的代码:

Flexible(
            child: StreamBuilder<QuerySnapshot>(
              stream: projects.snapshots(),
              builder: (BuildContext context,
                  AsyncSnapshot<QuerySnapshot> snapshot) {
                if (snapshot.hasError) {
                  return Text('Something went wrong');
                }

                if (snapshot.connectionState == ConnectionState.waiting) {
                  return Text("Loading");
                }

                return new ListView(
                  children:
                      snapshot.data.documents.map((DocumentSnapshot document) {
                    return new ListTile(
                      title: new Text(document.data['project_name']),
                      subtitle: new Text(document.data['project_description']),
                    );
                  }).toList(),
                );
              },
            ),
          ),

如果项目有任务,我想在项目描述下方显示它们,如果任务有子任务,我想在其父任务下方显示它们。

【问题讨论】:

  • 您可能对此article 感兴趣,它解释了如何使用云函数检索文档的子集合列表。

标签: firebase flutter google-cloud-firestore


【解决方案1】:

听起来您实际上是在问如何列出嵌套的子集合,这对于网络和移动客户端是不可能的。另见:

此外,所有 Firestore 查询都是浅层的,这意味着它们一次只考虑一个集合中的文档。没有深度或递归查询。

考虑改为在文档中维护项目列表,您可以直接get()。您可以使用该列表直接查询每个子集合。

【讨论】:

    【解决方案2】:

    这种情况有不同的实现方式,基本上子集合位于一个文档下,查询标识一组文档,当您知道查询仅标识一个文档时,Firestore 客户端不知道,即使知道,它也不知道该文档的完整路径。

    你需要执行一个查询来获取单个文档,然后你可以得到每个文档的子集合。

    你可以使用flutter here找到一个很好的例子。

    【讨论】:

      【解决方案3】:

      我遇到了类似的问题,并在流旁边使用了 bloc 提供程序, 我首先为 Json 解析创建了一个模型(在我的例子中,我有一个用户可以创建活动的应用程序,这些活动被保存为 UserData 集合中的子集合,文档 ID 是来自 FirebaseAuth 的用户 ID(现在是 Flutter 迁移中的用户). 目标是遍历每个用户的子集合 (UserCampaigns) 的 UserData 集合,并检索所有这些集合并使用 bloc.userCampaignRepository 显示在 UI 中:

          List<UserCampaignModel> UserCampaignList = [];
      CreateListofAllUserCampaigns(QuerySnapshot snapshot) async {
      var docs = snapshot.docs;
      for (var Doc in docs) {
        UserCampaignList.add(
            UserCampaignModel.fromEntity(UserCampaignEntity.fromSnapshot(Doc)));
      }
      return UserCampaignList;
      

      }

      Stream<List<UserCampaignModel>> getListUserCampaigns() async* {
      final collection = FirebaseFirestore.instance.collection('UserData');
      final List list_of_users = await collection.get().then((value) => value.docs);
      for (int i = 0; i < list_of_users.length; i++) {
        FirebaseFirestore.instance.collection("UserData")
            .doc(list_of_users[i].id.toString())
            .collection("UserCampaigns")
            .snapshots()
            .listen(CreateListofAllUserCampaigns);
      }
      yield UserCampaignList;
      

      }

      在集团中:我有 2 个事件,一个是通过监听流和调用加载器事件来启动事件加载。

           if (event is InitiateLoadOfAllUserCampaignsEvent) {
        yield AllUserCampaignsState.initial();
        try {
          
          _userCampaignSubscription?.cancel();
          _userCampaignSubscription = _userCampaignRepository
              .getListUserCampaigns()
              .listen((allCampaigns) {
                print("Load event is called");
            add(
              LoadAllUserCampaignsEvent(allUserCampaigns: allCampaigns),
            );
            
          });
        } catch (e) {
          print("error is ${e}");
          yield AllUserCampaignsState.allUserCampaignLoadFailure();
        }
      } else if (event is LoadAllUserCampaignsEvent) {
        yield* _mapLoadAllUserCampaignsEventToState(event);
      }}}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-08-06
        • 2021-03-04
        • 2021-07-12
        • 2021-08-02
        • 2020-02-03
        • 2019-02-17
        相关资源
        最近更新 更多