我正在构建一个任务管理应用程序,其中每个用户都有多个项目(集合),每个项目中都有任务(集合),每个任务中都有子任务。
我能够使用以下代码检索所有项目:
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(),
);
},
),
),
如果项目有任务,我想在项目描述下显示它们,如果任务有子任务,我想在其父任务下面显示它们。
答案 0 :(得分:4)
听起来您实际上是在询问如何列出嵌套的子集合,这对于Web和移动客户端是不可能的。另请参阅:
此外,所有Firestore查询都很浅,这意味着它们一次只考虑一个集合中的文档。没有深度查询或递归查询。
请考虑在文档中维护项目列表,您可以直接get()
。您可以使用该列表直接查询每个子集合。
答案 1 :(得分:1)
此方案有不同类型的实现,基本上子集合位于一个文档下,查询标识一组文档,当您知道查询仅标识一个文档时,Firestore客户端不知道,即使这样做,它也不知道该文档的完整路径。
您需要执行查询以获取单个文档,然后才能获取每个文档的子集合。
您可以使用抖动here找到一个很好的例子。
答案 2 :(得分:0)
我遇到了类似的问题,并且在流旁边使用了 bloc provider, 我首先创建了一个用于 Json 解析的模型(在我的例子中,我有一个应用程序,用户可以在其中创建活动,这些活动被保存为 UserData 集合中的子集合,文档 ID 是来自 FirebaseAuth 的用户 ID(现在用户在 flutter 迁移). 目标是遍历每个用户子集合 (UserCampaigns) 的 UserData 集合,并检索所有这些集合并使用 bloc 在 UI 中显示。userCampaignRepository:
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;
}
在 bloc 中:我有 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);
}}}