how to combine two Firestore collections?

56 Views Asked by At
Example code 
 
toys = toysRef.where('postState', isEqualTo: 'recruiting').orderBy('createdAt', descending: true).snapshots();
fruits = fruitsRef.where('postState', isEqualTo: 'recruiting').orderBy('createdAt', descending: true).snapshots();

hi I'm trying to combine or merge two streams I want to show toys and fruits order by desc with one StreamBuilder Widget There is a common field ['createdAt']

enter image description here

I want to implement like this. if some item added to firestore , it should show on realtime.

1

There are 1 best solutions below

1
Rusu Dinu On

You can use StreamGroup from rxdart to merge your toys and fruits.

StreamGroup<List<QuerySnapshot>> combinedStreams = StreamGroup<List<QuerySnapshot>>.merge([
  toysRef.where('postState', isEqualTo: 'recruiting').orderBy('createdAt', descending: true).snapshots(),
  fruitsRef.where('postState', isEqualTo: 'recruiting').orderBy('createdAt', descending: true).snapshots()
]);

and to finally have them sorted in a stream, you could have:

StreamBuilder<List<QuerySnapshot>>(
  stream: combinedStreams,
  builder: (BuildContext context, AsyncSnapshot<List<QuerySnapshot>> snapshot) {
    List<QueryDocumentSnapshot> combinedData = [];
    for (QuerySnapshot snap in snapshot.data) {
      combinedData.addAll(snap.docs);
    }

    combinedData.sort((a, b) => b['createdAt'].compareTo(a['createdAt']));

    return ListView.builder(
      itemCount: combinedData.length,
      itemBuilder: (context, index) {
        // Build your UI
      }
    );
  }
)

You should use ListView.builder so that you have a performant list, and not render all the elements at once (would really lag your UI if you'd have a lot of elements).

Don't forget to check if snapshot has errors or is empty so that you can display a loader to the user or an error message.