Reputation: 563
I'm using Flutter with firebase for my app.
I started my application by putting all my code in the main. dart I now want to organize my files well but I am facing a problem.
I created a service folder, with a database. dart file in which I made a class to find my items in firestorm
the problem is that I do not pass in the snapshot. docs.map ((doc))
here is my code in database. dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutterfirebase/models/todo_model.dart';
class DatabaseService {
DatabaseService();
final CollectionReference itemsCollection =
FirebaseFirestore.instance.collection("items");
Stream<List<TodoItem>> get todos {
return itemsCollection.snapshots().map((QuerySnapshot snapshot) {
inspect(snapshot.docs);
return snapshot.docs.map((DocumentSnapshot doc) {
print('here');
inspect(doc);
return TodoItem(text: doc.data()['text'], done: doc.data()['done']);
});
});
}
}
the print(snapshot.docs.length);
returns 4. The inspect(snapshot.docs)
works, I can see my 4 queryDocumentSnapshot with my id
but the print('here')
does not appear, nor the inspect(doc)
can you help me figure out what's going on, please?
here are the versions of the packages
firebase_core: ^1.0.2
cloud_firestore: ^1.0.3
Thanks
Upvotes: 0
Views: 268
Reputation: 36
The print('here')
does not appear because the transformation function provided to .map
is not executed immediately. map
returns an Iterable and, according to the official docs:
The returned iterable is lazy, so it won't iterate the elements of this iterable until it is itself iterated, and then it will apply toElement to create one element at a time
In other words, since you do not iterate over the result of your map
, the function inside map
is never called. One way to force the iteration is to convert the result of map
to a List using toList()
method.
In Dartpad, you can test this by running the following example:
final List<int> numbers = [1, 2, 3];
final iterable = numbers.map((num) {
print('inside map, num is: $num');
return num + 1;
}).toList();
If you try and remove the toList()
from the result of the map
above the print
is never executed.
To address the original example, please try adding toList
as follows:
snapshot.docs.map((DocumentSnapshot doc) {
print('here');
inspect(doc);
return TodoItem(text: doc.data()['text'], done: doc.data()['done']);
}).toList();
Upvotes: 0
Reputation: 140
I think you should return QuerySnapshot from the stream not DocumentSnapshot, just like this
Stream<List<TodoItem>> getSomeoneItems() {
return FirebaseFirestore.instance.collection('items')
.snapshots()
.map((qSnap) =>
qSnap.docs.map((doc) => TodoItem.fromJson(doc.data())).toList());
}
then you can use this stream in your view inside StreamBuilder widget.
Upvotes: 3