0

im trying to present a listview of multiple streams in my app,but i cant think about a good way of doing this.i'v searched online for a solution and couldn't find a valid one. firestore code:

      Stream<QuerySnapshot<Map<String, dynamic>>> getGroupStream<T>() {
        List<Stream<QuerySnapshot<Map<String, dynamic>>>> list = [];
        List<String> members = [];
        _fireStore
        .collection("groups")
        .doc(gid)
        .get()
        .then((docSnapshot) { 
          members = docSnapshot.data()!["members"];
          for (String member in members) {
            list.add(_fireStore
              .collection("users")
              .doc(member)
              .collection("groceries")
              .snapshots());
          }
        });
    
        return StreamGroup.merge(list);
      }

content build:

Widget _buildContent(BuildContext context, Stream<QuerySnapshot> stream) {
    return StreamBuilder<QuerySnapshot>(
      stream: stream,
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          final docs = snapshot.data!.docs;
          if (docs.isEmpty) {
            return Center(
                child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text(
                  "The list is empty",
                  style: TextStyle(fontSize: 32, color: Colors.black54),
                ),
                Text(
                  "Add a new item to get started",
                  style: TextStyle(fontSize: 16, color: Colors.black54),
                ),
              ],
            ));
          }
          int index = -1;
          final cards = docs
              .map((doc) => CrossableListTile(
                  doc, _showSetGroceryButtomSheetForm, index++))
              .toList();
          return Container(
            padding: EdgeInsets.symmetric(vertical: 20, horizontal: 10),
            child: ListView(
              children: cards,
            ),
          );
        } else if (snapshot.hasError) {
          return Center(
            child: Column(
              children: [Text("An error has occured while loading you'r list")],
            ),
          );
        }
        return Center(
            child: CircularProgressIndicator(
          color: barColor,
        ));
      },
    );
  }

  _showSetGroceryButtomSheetForm(
      BuildContext context, String name, String amount) {
    setState(() {
      _changeIsButtomSheetOpen();
    });

    showBottomSheet(
        context: context,
        builder: (context) => Provider<Function>(
            create: (_) => _changeIsButtomSheetOpen,
            builder: (context, w) => GestureDetector(
                onVerticalDragStart: (_) {},
                child: AddGroceryForm(Grocery(name: name, quantity: amount)))));
  }

body:

body: TabBarView(children: [
        _buildContent(
          context,
          db.getGroupStream(),
        ),
        _buildContent(
          context,
          db.getPesonalStream(),
        ),
      ]),

iv tried so many different stuff and nothing works. the one stream display works perfectly, the multi-stream display doesnt.

Victor Eronmosele
  • 7,040
  • 2
  • 10
  • 33

1 Answers1

0

Update the getGroupStream method to this below:

Stream<QuerySnapshot<Map<String, dynamic>>> getGroupStream<T>() {
  List<Stream<QuerySnapshot<Map<String, dynamic>>>> list = [];

  _fireStore.collection("groups").doc(gid).snapshots().forEach(((docSnapshot) {
    List<String> members = docSnapshot.data()!["members"];

    list = members
        .map((member) => _fireStore
            .collection("users")
            .doc(member)
            .collection("groceries")
            .snapshots())
        .toList();
  }));

  return StreamGroup.merge(list);
}

This method gets the stream for _fireStore.collection("groups").doc(gid) by using .snapshots() instead of using .get().then() as in your question.

Victor Eronmosele
  • 7,040
  • 2
  • 10
  • 33