This is my stream function:
Stream<QuerySnapshot> getPortfolios() {
return db
.collection('users')
.doc(authService.getUser().uid)
.collection('portfolios')
.snapshots();
}
In the StreamBuilder
I get the list like this:
portfolios = snapshot.data!.docs;
That gives my a list but a list of JsonQueryDocumentSnapshot
. With each item I can do .data()
and I get the info I need, but how could I get this map directly in the list without calling extra methods?
I tried this old answer but it doesn't work anymore:
final QuerySnapshot<Object?>? ds = snapshot.data;
final Map<String, dynamic> map = ds!.data; // this .data is not recognised
CodePudding user response:
You can use ".docs" on the snapshot to get a list of QueryDocumentSnapshot which have some of the same properties as a map, so you can directly reference a value like im doing below:
List<QueryDocumentSnapshot> data = snapshot.data!.docs;
String name = data[i]['name']
Here is a full example :
StreamBuilder<QuerySnapshot>(
stream: db.collection('users').snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasData) {
List<QueryDocumentSnapshot> data = snapshot.data!.docs;
return ListView.builder(
itemCount: snapshot.data!.size,
itemBuilder: (context, i) {
return Text('${data[i]['name']}');
},
);
} else {
return CircularProgressIndicator();
}
},
),
Alternatively you can map the Stream to any object like this:
Stream<QuerySnapshot<Map<String, dynamic>>> snaphot = db
.collection('users')
.doc(authService.getUser().uid)
.collection('portfolios')
.snapshots();
//Map to an object (note that you need to create a "fromJson" method for your object.
Stream<List<YourObject>> dataStream = snaphot.map((list) => list.docs.map((doc) => YourObject.fromJson(doc.data())).toList());
Now you can use the "dataStream" in your stream builder and directly reference the items in the list with "snapshot.data".
// snapshot.data is now the type:
List<YourObject>