Home > Software design >  Flutter: get a list of maps when using Firebase snapshots
Flutter: get a list of maps when using Firebase snapshots

Time:08-27

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>
  • Related