I'm querying Firestore and getting a Stream back as a Stream of QuerySnapshots. I need to map the included Documents in the stream to a List of objects.
The code below doesn't work (obviously)...maybe I'm just looking at this entirely wrong.
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;
}
With the code above, since it doesn't wait for the entire stream (or any of it actually), list is always returned as null. In short, how do I convert my stream to a List?
Note: I'm pretty new to the world of Dart, so go easy on me :)
Thanks!
A QuerySnapshot contains zero or more DocumentSnapshot objects. It can be enumerated using the documents property and its size can be inspected with isEmpty and count .
A QuerySnapshot contains the results of a query. It can contain zero or more DocumentSnapshot objects. Subclassing Note: Cloud Firestore classes are not meant to be subclassed except for use in test mocks. Subclassing is not supported in production code and new SDK releases may break code that does so.
A QuerySnapshot contains zero or more DocumentSnapshot objects representing the results of a query. The documents can be accessed as an array via the docs property or enumerated using the forEach method. The number of documents can be determined via the empty and size properties.
First of all, think about this: this function has to return very quickly. All functions do, otherwise UI would hang. However, you are expecting the function to return something that comes from the internet. It takes time. The function has to return. There is no way for a function to simply do a network request and return you the result. Welcome to the world of asynchronous programming.
Furthermore, the stream you have is not a stream of DocumentSnapshot
s (which you can convert to UserTask
s), but a stream of QuerySnapshot
s (which you can convert to List<UserTask>
s). Notice the plural there. If you simply want to get all your UserTask
s once, you should have a Future
instead of a Stream
. If you want to repeatedly get all your UserTask
s after each change, then using a Stream
makes sense.
Since you said you want to get a List<UserTask>
, I'm assuming you want to get the collection of UserTask
s only once.
Here's what your code becomes in this light:
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
}
Now if you really wanted to use a stream, here's how you could do it:
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
}
}
Hope it helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With