60 Days of Flutter :Building a Messenger : Day 24–26 : Building a Animated Progress Fab and the Contacts Bloc in Flutter
In the last post we created the UI for the Contacts Page. Today we’ll be creating the UI for adding a new contact and also writing the ContactsBloc to support the business logic for the Contacts Page.
It’s already 1 a.m. at the time of writing this post and that’s because I got stuck at quite a few things while doing this task, You know those weird errors and issues you just seem to have no solution to sometimes!
But thankfully I was able to fix them and so here we go. Let’s start!
Animating the FloatingActionButton and the Add-User ModalSheet
Before diving into the code let’s see what we’ll be building.
To start with we need a BottomSheet with rounded top corners. The default BottomSheet has a weird issue with TextField widget. It does not push the TextField up when keyboard is displayed and thus the TextField gets hidden behind it. There’s a workaround for it and we’ll be using the modifed BottomSheetFixed.dart from here to fix it.
Create the showAddContactsBottomSheet method.
It uses a BoxDecoration for the rounded edges. The GradientFab is the same from the last post.
The getButtonChild method returns the Icon for the FAB based on the state.
Creating The ContactsBloc
Create the ContactsBloc inside blocs/contacts using the BlocGenerator plugin. Or else create it manually. Once generated you should have the following file structure.
I’ve explained what they are in a old post here.
Create the States and the Events
Let’s now create the Bloc for mapping events to state.
This should give you a visual blueprint of which event does what. Now we need to implement the underlying logic of interaction with Firebase.
The Problem
I wanted to have a unique constraint on username field, so that duplicate contacts or profiles can’t be created. Unfortunately Firebase out of the box does not come with a Unique constraint.
The solution to this is to maintain a mapping of uid-> username and username->uid . We already have a mapping of uid->username under /users collection on our FireStore. Let’s create the second mapping.
Also update and add rules for this in the rules section of FireStore.
https://gist.github.com/adityadroid/1ce127903133ba471f352ad2e105c351
Retrieving Session Uid from Firebase each time is a bit slow. Let’s cache it in our local preferences. Add this to your pubspec.yaml dependencies.
shared_preferences: ^0.5.3+4Create Utils/SharedObjects and define a global SharedPreferences
We’ll be saving the Uid in SharedPreferences with signInWithGoogle method of AuthenticationProvider .
Now let’s write the add and fetch contact methods in UserDataProvider . For fetching the data we’ll be using a Stream.
For handing errors on the UI we’re throwing custom exceptions for each condition encountered. Let’s see what these exceptions are.
Wiring the Bloc with the UI
Our Bloc is ready to be wired with the UI. We’re using BlocBuilder and BlocListener to respond to different states.
And that’s it for today. The tests will all fail because we haven’t updated them with a mocked version of SharedPreferences . I’ll be working on that and other stuff tomorrow.
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
#19Replaced State for contactlist with Stream
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
- 60 Days Of Flutter : Building a Messenger from Scratch
- 60 Days of Flutter : Day 1 : Creating the App
- 60 Days of Flutter : Day 2 : Setting Up A CI With Flutter
- 60 Days of Flutter : Day 3–4 : Building a Chat Screen in Flutter
- 60 Days of Flutter : Day 4–5 : Widget Testing With Flutter
- 60 Days of Flutter : Day 6–7 : Implementing a Slideable Widget Using Bottomsheet in Flutter
- 60 Days of Flutter : Day 8 : Changing The Launcher Icon and Implementing GestureDetector
- 60 Days of Flutter : Day 9–10–11 : Creating Awesome Register Screen in Flutter
- 60 Days of Flutter : Day 12–14 : Understanding BLoC Pattern in Flutter
- 60 Days of Flutter : Day 15–17 : Implementing Registration Screen using ‘flutter_bloc’
- 60 Days of Flutter : Day 18–19 : Unit Testing in Flutter using ‘ mockito’
- 60 Days of Flutter : Day 20–21 : Unit Testing a Bloc in Flutter
- 60 Days of Flutter : Day 22–23 : Building a Modern Contacts Page in Flutter
- 60 Days of Flutter : Day 24–26 : Building a Animated Progress Fab and the Contacts Bloc in Flutter
- 60 Days of Flutter : Day 27–29 : Sending and Retrieving Messages from Firebase using BLOC
- 60 Days of Flutter : Day 30–32 : Firebase Chat UI using Stream and Bloc
- 60 Days of Flutter : Day 33–35 : Paginating data from Firestore using Firebase Queries
- 60 Days of Flutter : Day 36–38 : Seamlessly Upload Files to Firebase Storage
- 60 Days of Flutter : Day 39–41 : One UI Inspired Attachments Showcase Page
- 60 Days of Flutter : Day 42–45 : Creating the Home Page & Quick Peek BottomSheet for Messages
- 60 Days of Flutter : Day 45–47 : Adding Dark Mode to a Flutter App
- 60 Days of Flutter : Day 48–50 : Creating the Settings Page using Bloc
- 60 Days of Flutter : Day 51–54 : Unit Testing Firebase Providers with Mockito
- 60 Days of Flutter : Day 55–56 : Deploying Firestore Security Rules using Firebase CLI
- 60 Days of Flutter : Day 60 : Wrapping It Up
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!
