60 Days of Flutter :Building a Messenger : Day 33–35 : Paginating data from Firestore using Firebase Queries

Aditya Gurjar
5 min readSep 21, 2019

--

In the last post, we built the ChatBloc. At the end of the post I listed out few issues with the ChatBloc that we built.

We’re loading all the messages at once, We’ll also need to implement pagination for the messages.

On swiping between the pages, the state of the page does not persist, they’re getting rebuilt everytime. Also the messages get jumbled up between the pages. This also needs to be fixed.

The TextField overflows the AppBar.

On clicking the contact, it takes a little bit time before the data is returned, we’ll need to implement a Local Storage to cache this data locally as well.

The last item in the list will make for a separate post which I’ll be doing in the coming days. We’ll be taking up all the other issues in the list, today.

Oh, and before we start, for no reason at all here are some sneaks into DevFest19, Bangalore which I happened to attend today!

Alright, Let’s get started!

Implementing Pagination on Chat Screen

Our pagination scheme is going to be a bit different than usual because we also need to keep track of new incoming messages. Let’s first try to understand it with a diagram.

To start with, our chat screen now has two different events.

  • FetchMessagesEvent : Triggered when the chat is first opened. It retrieves the latest 20 messages and returns a Stream<List<Message>> . This stream will emit any new messages received.
  • FetchPreviousMessagesEvent : Triggered when user reaches the top of the page. It returns a List<Message> of 20 messages previous 20 messages. (and the next 20 after that, on next scroll to top).

The Implementation

We have the usual Event-Bloc-State trio to start with. Let’s take a look at them first to see which one is doing what. The two Events we talked about above,

The associated Bloc.

And the resultant States are.

Firebase Query

Cloud Firestore provides powerful query functionality for specifying which documents you want to retrieve from a collection or collection group. This basically allows you to apply certain constraints, ordering or filters while retrieving the data. Let’s take a look at how we’re doing it.

We had the getMessages() previously as well, it does the same thing as before i.e. gives a stream of the latest 20 messages.

The new thing here is the getPreviousMessages() method. It takes the documentID of the top most message in the chat screen, and returns the next 20 messages after it. So every time user reaches the top, the next 20 messages are loaded. To achieve this, it uses the different query operations available with Firebase to achieve this.

We also want to make sure that everytime the user reaches the top of the ChatList , FetchPreviousMessageEvent is trigged. This is how our ChatListWidget looks after these modifications.

PageView Persistance

Next up, we wanted the PageView data to persist between Page switches and also fix the BottomOverFlow error which showed everytime the keyboard came up.

We’ll be using AutomaticKeepAliveClientMixin to keep our PageView pages alive. Modify your ConversationPage to add this mixin.

The BottomOverFlow error was because we used the Expand Widget and it was getting pushed everytime the keyboard showed up, in turn shrinking the AppBar . Replaced it with a Stack and everything works as we want it to.

Let’s see it in action.

Neat!

In the next article we’ll take a look at caching data using a Local Storage technique.

Hit me up in the comments below or Twitter or Linkedin or Instagram if you have any queries or suggestions or just for a casual tech talk maybe? See you guys in the next one!

Code Changes

#23 Pagination and other ConversationPage Fixes

How Can You Contribute?

Posts In This Series

Show Your Support

Press the clap button below if you liked reading this post. The more you clap the more it motivates me to write better!

--

--

Aditya Gurjar
Aditya Gurjar

Written by Aditya Gurjar

Mobile Engineer. Writing Mostly about Mobile Dev, Mobile DevOps, and a lil bit of life.

Responses (2)