In the last post we created the Attachments Page. We now can add contacts, send/receive messages and attachments in our app. The one key thing missing though is the home page. The reason why I kept the home page for later was because I wasn’t sure of how I wanted it to be. In the end I’ve decided that the user will be able to view all his chats at two different places.

The Home Page .

. The Chat Screen, using a BottomSheet which is always accessible by sliding over the TextBox .

This is how both of them would look

Create The HomeBloc

Start by generating the HomeBloc at blocs/home using bloc_code_generator. Check this post if you don’t know how to do it.

Let’s define the Events first.

We have two events here.

FetchHomeChatsEvent is triggered when the homepage is first opened.

is triggered when the homepage is first opened. ReceivedChatsEvent is triggered when there are any updates in the HomePage chats list.

And now the States .

And now the HomeBloc .

The HomeBloc creates a Stream from ChatRepository and whenever there are any updates, it triggers a ReceivedChatsEvent . This Event then yields FetchedHomeChatsState as the final state with data.

Retrieving the Data

Now comes probably the hardest part of today’s task - Retrieving the Conversation data from FireStore .

Big Brain Time!

Conversation Model

Every conversation row will show/do few different things. Let’s see what they are:

User details (name, profile pic) of the contact we’re chatting with.

Latest message in the chat along with time of sending that message.

And clicking it should open the Chat Page for that conversation (thus we’ll need the Chat ID).

Based on above info we can define our Conversation model as.

We’ll also need to add new factories to our User and Message Model.

Check Code Changes section for the complete changes in Message.dart

Modifying Database Structure

If you remember, the chats Collection schema for our DB looked something like this.

There’s one fundamental issue here. We have the latest message and the list of members. But the profile details(eg. name,profile pic) for the members are missing.You might think what’s the big deal? We can always read them from users Collection.

We definitely can but the read complexity in that case will be much higher. It will increase as the number of chats increase because for every chat we’ll have to,

Take the user’s username. Get his UID from the username-uid map. Use that UID to retrieve the user details from users collection. Repeat this for all the N chats.

To reduce this read complexity, we make a one time compromise on our write complexity. This technique of improving read speeds by duplicating data is called Fanning, in NOSQL Databases.

Lets update the ChatProvider.createChatIdForUsers method and introduce a new array called membersData .

Reading the Conversations as Stream

Here’s the getConversations method.

It reads all the chats of which the current logged in user is a member of.

of. Sorts them based on latestMessage‘s timestamp .

. Maps the resulting documents to List<Conversation> .

The Home Page UI

The HomePage UI has a SliverAppBar and SliverList with a GradientFab clicking which opens the ContactsPage.

Each individual row is a ChatRowWidget .

The BottomSheet on Chat Page

The BottomSheet on Chat Page uses the exact same logic but with a ListView .

And the end result looks pretty damn great I’d say!

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

#26 Added Home Page

How Can You Contribute?

Open issues with suggestion of better approaches or ideas for the app.

Connect with me on Twitter or Linkedin or Instagram.

Star the Github repository.

Share the series on Twitter.

Follow me on Github.

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!