0

I have managed to merge 2 streams of data (in my app, i expect to be merging a lot more than 2 streams on this particular page) into a single stream which i have named groupedStream and this stream is being fed into my StreamBuilder.

However, the issue comes with displaying the data. It is only showing data from one of the streams. And yet if i put a print function with a string, i can see that string being printed the exact number of times i'd expect it to be printed.

Let me explain it some more. I have a publicFeed collection on firestore where the posts of people who post something in my app get saved. When a follower opens this particular page, the app will get his list of followings(people he is following) and create merged stream with each of their publicFeed collections and pipe all this data into a single list view. So the user can see what they have all posted of recent. I figured this system is a lot better , faster, cheaper and more scalable than the app writing to each follower's personal "privateFEed" collection, because picture someone with 2million followers. That is 2 million writes and later on, 2 million reads.

So, this in mind, i logged in as two of myusers and posted some dummy content. 3 posts from each and then after logging out, i logged in using an account that follows the both of them to see if the stream merging works. Sadly, its only showing me posts from one of them. But the print shows 6 prints. When i made it print out the ID of the posts that are being worked on at the time of the print, i saw that its the exact same posts that are being shown. But i found it odd that the number exactly matches the total number of posts i expect to see on the page.

How can i get my stream builder to work well? I have scoured the internet all day but have failed to find it.

Relevant code is below:

This is the code for finding the list of people that the current user follows: It gets executed in init state. Followings is a list of type String that just holds the followings' user IDs. Its more or less useless. IFollowPeople is a bool that i use to easily check whether or not the ui should go through the stress of building a stream builder and what not, instead of just showing an image like "sorry, you dont follow anyone. Please go be more social and follow people"

 getFollowingCount() async {
followingsStreams = [];
followings = [];
try {
  await FirebaseDatabase.instance
      .reference()
      .child("following")
      .child(uid)
      .once()
      .then((value) {
    if (value.value != null) {
      int count = 0;
      Map<dynamic, dynamic> followaz = new Map();
      followaz = value.value;
      followaz.forEach(
        (key, value) {
          print(key);
          followings.add(key);
          followingsStreams.add(Firestore.instance
              .collection("posterPublicFeed")
              .document(key)
              .collection(key)
              .snapshots());

          count++;
        },
      );

      if (count == followaz.length) {
        groupedStream = StreamGroup.merge(followingsStreams);
        // print(followingsStreams.toString());

        if (mounted) {
          setState(() {
            iFollowSomePeople = true;
          });
        }
      }
    }
  });
} catch (e) {
  print("error getting followers $e");
}

}

What comes next i the errant stream builder in the body. Relevant code is :

StreamBuilder(
        stream: groupedStream,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            if (snapshot.data == null) {
              return Text("You have no posts in your private feed yet");
            } else {     dynamic privatePosts = snapshot.data.documents;

              return ListView.builder(
                  itemCount: privatePosts.length,
                  itemBuilder: (context, index) {
                    String postID = privatePosts[index].documentID;
                    print(postID);
                    return Container(
                      child: StreamBuilder(
                        stream: Firestore.instance
                            .collection("posts")
                            .document(postID)
                            .snapshots(),
                        builder: (context, snapshot) {
                          print("I printed a post YOOOOOO.");
                          print("The postID is $postID");
                          if (snapshot.hasData) {
                            return Text("This is a post");
                          } else {
                            return Text(
                                "Post not found. Please check your internet connection");
                          }
                        },
                      ),
                    );
                  });

              
            }
          } else {
            return Scaffold(
              body: Column(
                children: <Widget>[
                  SizedBox(
                    height: MediaQuery.of(context).size.height * 0.4,
                  ),
                  Text(
                    "Just a sec...",
                    style: TextStyle(
                        fontSize: 16, fontWeight: FontWeight.w600),
                  ),
                  SpinKitDoubleBounce(
                    color: Colors.blue,
                  ),
                ],
              ),
            );
          }
        },
      ),

When i run it, this is what i get. Please note the number of "I printed a post" texts in the debug console and the number of texts on the screen. ALso useful to note is the fact that there is a sum of 6 posts in total that this user is expecting to see on screen. 3 per person they're following. Help please.

Screenshot from my desktop

Simeon
  • 692
  • 1
  • 6
  • 12

1 Answers1

0

I believe the issue is due to that StreamBuilder will only take the most recent snapshot and may miss some of the initial snapshots. Specifically it may miss the initial data in each of the snapshots.

As new data comes into any of the streams it should pick up those snapshots too.

This question and this question provides some solutions on how to solve it.

Kirk
  • 3
  • 3