1

I have a comment page for each post in my app that I use streambuilder to fetch the comments from Firebase database. For each comment, I am displaying user's image and their comment.

To get the user's image, I need to use a futurebuilder to find the user in the userData document and then grab the image url and display it (users can change their image profile, name, etc. at any time and I have to grab the updated one from the userData document every time I want to display their name or image anywhere). Here is the code I use:

StreamBuilder(
  stream: Firestore.instance
      .collection('posts')
      .document(postId)
      .collection('postComments')
      .orderBy(
        'createdAt',
        descending: true,
      )
      .snapshots(),
  builder: (ctx, chatSnapshot) {
    if (chatSnapshot.connectionState == ConnectionState.waiting) {
      return Center(
        child: CircularProgressIndicator(),
      );
    }
    final chatDocs = chatSnapshot.data.documents;
    return ListView.builder(
      shrinkWrap: true,
      reverse: true,
      itemCount: chatDocs.length,
      itemBuilder: (ctx, index) {
        return FutureBuilder(
          future: Firestore.instance
              .collection('userData')
              .document(userId)
              .get(),
          builder: (context, userSnapshot) {
            if (userSnapshot.connectionState == ConnectionState.waiting) {
              return Container(
                child: CircularProgressIndicator(
                  valueColor:
                      AlwaysStoppedAnimation(Color.fromRGBO(0, 0, 0, 0)),
                ),
              );
            }
            final userData = userSnapshot.data;
            User commentor = User.fromDocument(userData);
            return Padding(
              padding: const EdgeInsets.all(20.0),
              child: Row(
                children: [
                  CircleAvatar(
                    backgroundImage: NetworkImage(
                      commentor.userImage,
                    ),
                  ),
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Container(
                      width: MediaQuery.of(context).size.width * 0.5,
                      padding: EdgeInsets.all(10),
                      color: Colors.grey,
                      child: Text(
                        chatDocs[index]['comment'],
                        style: TextStyle(
                          color: Colors.black,
                        ),
                        textAlign: TextAlign.start,
                      ),
                    ),
                  ),
                ],
              ),
            );
          },
        );
      },
    );
  },
);

When I scroll from bottom to top (most recent to older comments), the scrolling is very smooth with no problem, but when I get to the end of the list (oldest comment) and start scrolling back down, there is a weird jump between the comments and the scrolling is not smooth at least for the first few scrolls.

I have This screencapture here which shows the weird scrolling behavior. Why does this happen?

Thanks!

AkbarB
  • 460
  • 7
  • 24
  • is this a 1:1 chat or a group chat – CoderUni Aug 17 '20 at 04:45
  • Listview.builder builds its children lazily. Meaning that it will build it only if the widget is appearing on screen. Whats even worse is than you are wrapping the Listview.builder inside a Streambuilder and you are wrapping the Listview.builder's children with FutureBuilder. You definitely don't want to do that. Instead, you'd have to use only one Streambuilder that has a model containing your data you are fetching in both your Streambuilder and FutureBuilder. The key here is to use pagination. – CoderUni Aug 17 '20 at 04:51
  • Fetch only the last 10 messages then when the user scrolls up, fetch the last 10 messages after the first 10 messages that you've fetched. Here is an example: https://medium.com/flutterdevs/pagination-in-flutter-with-firebase-firestore-96d6cc11aef2 Also, you definitely don't want to use firestore in a chat app. Use firebase rtdb. See: https://www.promaticsindia.com/blog/cloud-firestore-vs-realtime-how-to-choose-the-best-database-for-your-mobile-app/ Take a look at the billing costs in firestore. – CoderUni Aug 17 '20 at 04:51
  • well this particular issue is happening in a post comment section of the app which is actually similar to any other social app (multiple people can comment on the post) – AkbarB Aug 17 '20 at 11:38
  • Ok. I try to to explore with the pagination and see what I can do. I have two collections as you can see. One is userData and the other one is posts. like I said, userData document fields (user image) can change after they comment is posted. I want the user image change next to the comment when the comments screen is open. So, I have to fetch the image from the userData which keeps the reference to the updated user image and hence the futurebuilder inside the Listviewbuilder – AkbarB Aug 17 '20 at 11:43
  • There is a 1:1 chat section in the app as well and I am using cloud firestore for that too, but from what you are saying and reading that blog post, I'm guessing it will be very expensive and I should instead use realtime db for the 1:! chat. correct? – AkbarB Aug 17 '20 at 11:46
  • 1
    Yes. Use firebase rtdb. NEVER USE FIRESTORE for chats. It is going to be really expensive and costly! You are charged more based on the amount of reads. Your chat app will be reading each and every message by a lot and its only showing you message which are a few bytes of data. Better use firebase rtdb since those are only a few bytes of data. See https://stackoverflow.com/questions/47879031/firebase-database-structure-for-chat-application as well. – CoderUni Aug 17 '20 at 11:58
  • Ok. Thanks for the tip. I still need to use firestore for the rest of the app, so I guess I need to figure out how to use Firestore and rtdb together. – AkbarB Aug 17 '20 at 12:27
  • its not really hard to use them together. just don't make the expensive mistake. You really don't wanna get billed that much. – CoderUni Aug 17 '20 at 13:20

0 Answers0