0

As many others, I have an app with chat functionality. I have a StreamBuilder<QuerySnapshot> that listens to new chat messages, and a ListView.builder that shows them. I'm looking for a good way to paginate the messages, but none of the solutions I have found works for me, since I always have to listen to new messages.

One of the things I tried was this code, but that didn't seem to work even if the author said he had updated the code.

Each chat message has it's own document in a collection, so right now I just fetch all the documents in the collection and order them by a time field. However this only works for about 20 messages before performance suffers, so I would be very glad if someone could help me with this.

Hannes Hultergård
  • 1,157
  • 1
  • 11
  • 33

1 Answers1

2

I guess you are showing the messages sorted by creation date, right? Why dont you paginate using the date then?

chatcollectionref.
where("creationdate", "<", enddate)
... // Add more conditions if needed
.orderBy("creationdate","desc").limit(20).get()

Start with enddate far in the future then update it to the creation date of the last message you retrieve and just paginate.

EDIT: a bit more details...

  1. First run of the query: enddate = new Date(2100, 1, 1) and you get the first 20 messages and display them
  2. The user scrolls down and reach the last message
  3. Run again the query: enddate = creationdate of the last message you have already retrieved, and you get the 20 next
  4. Loop back to 2

Works well in my chat app

l1b3rty
  • 3,333
  • 14
  • 32
  • I can do that, but what if the user wants to scroll up to see older messages? If i just add a limit to 20 you can't see older messages unless I specify where to start with for example `.startAfterDocument()`, and that's where my problem is; I can't do that while still listening to new documents as far as I know – Hannes Hultergård Jul 13 '20 at 10:06
  • Of course you can, that's why you change enddate as the user scrolls. You still only retrieve 20 messages but you start late – l1b3rty Jul 13 '20 at 10:08
  • oh, sorry. Yeah, that might work. Will try it right now – Hannes Hultergård Jul 13 '20 at 10:11
  • This works, although it is a bit choppy. But I think I can solve that by overlapping the pagination a bit. My problem now is how I can now when the user has reached the end, and preferably never show less than 20 documents. Do you know how I can achieve that? – Hannes Hultergård Jul 13 '20 at 12:32
  • "Choppy"? What would be another solution? You new question is about UI scrolling and wold deserve an entire new question – l1b3rty Jul 13 '20 at 12:52
  • 1
    @HannesHultergård if this answer was helpful, please consider upvoting and marking it as accepted. If you have more questions regarding your original issue please post a comment here. Otherwise, if you have more questions which relate to a new issue, such questions may warrant the need for creating a whole new question. Thanks! – sllopis Jul 14 '20 at 12:40
  • How does this solution function at all? How are you listening to new messages at the top while also appending older messages at the bottom? – erotsppa Mar 06 '23 at 17:54
  • @erotsppa yes, I have a snapshot listener for new messages. And then some additional logic for cases when the app goes offline and the listener does not pick all new messages when it goes back online – l1b3rty Mar 06 '23 at 18:37
  • @l1b3rty I'm currently implementing a simple list that needs to be in sync with firestore. It's seemingly impossible as outlined in detailed here https://stackoverflow.com/questions/75647101/what-is-the-correct-with-to-do-pagination-with-firebase-firestores-querysnapsho essentially the gist of it is that (1) I need a listener to track the changes coming at the top of list (sorted by timestamps) so that as new items are added I am notified but (2) I also need pagination so that when the user reaches the end of list, I need to fetch the next page but the original querySnapshot cannot do that – erotsppa Mar 06 '23 at 20:31
  • @erotsppa use a listener for the last docs and separate get queries for the pagination. I have tried to answer your question – l1b3rty Mar 07 '23 at 10:25