我正在查询Firestore,并将流作为QuerySnapshots流返回。我需要将流中包含的文档映射到对象列表。
下面的代码(显然)不起作用...也许我只是在看这完全错误。
List<UserTask> getUserTaskList() {
List<UserTask> list;
Stream<QuerySnapshot> stream =
Firestore.instance.collection('userTasks').snapshots();
stream.listen((snapshot) {
snapshot.documents.forEach((doc) {
UserTask userTask = UserTask(
doc.data['id'],
doc.data['Description'],
etc...);
list.add(userTask);
});
});
return list;
}
使用上面的代码,因为它不等待整个流(或实际上不等待任何流),所以list始终以null返回。简而言之,如何将流转换为列表?
注意:我对Dart领域还很陌生,所以请放轻松我:)
谢谢!
答案 0 :(得分:0)
首先,考虑一下:此函数必须非常快速地返回。所有功能都可以,否则UI会挂起。但是,您期望函数返回来自互联网的内容。这需要时间。该函数必须返回。函数无法简单地进行网络请求并返回结果。欢迎来到asynchronous programming的世界。
此外,您拥有的流不是DocumentSnapshot
s流(您可以将其转换为UserTask
s),而是QuerySnapshot
s流(您可以将其转换为List<UserTask>
个)。注意那里的复数。如果您只想让所有UserTask
一次,则应该使用Future
而不是Stream
。如果您想在每次更改后重复获得所有UserTask
,则可以使用Stream
。
由于您说过要获取List<UserTask>
,所以我假设您只想获取UserTask
的集合。
根据以下内容,您的代码将变为:
Future<List<UserTask>> getUserTaskList() async {
QuerySnapshot qShot =
await Firestore.instance.collection('userTasks').getDocuments();
return qShot.documents.map(
(doc) => UserTask(
doc.data['id'],
doc.data['Description'],
etc...)
).toList();
}
main() async {
List<UserTask> tasks = await getUserTaskList();
useTasklist(tasks); // yay, the list is here
}
现在,如果您真的想使用流,请按以下步骤操作:
Stream<List<UserTask>> getUserTaskLists() async {
Stream<QuerySnapshot> stream =
Firestore.instance.collection('userTasks').snapshots();
return stream.map(
(qShot) => qShot.documents.map(
(doc) => UserTask(
doc.data['id'],
doc.data['Description'],
etc...)
).toList()
);
}
main() async {
await for (List<UserTask> tasks in getUserTaskLists()) {
useTasklist(tasks); // yay, the NEXT list is here
}
}
希望有帮助。