Flutter and Firebase (II): Firestore.
By: Gustavo Muñoz
Tags: Firestore, Flutter, Firebase, Dart

Well, now that we have our login working, let’s create a protected application. Due to show user data and secret messages, we need.

A login page to stop unauthorized people. A profile page to show the user data. A feed page to show the secret messages of the user.

So now, in order to store user data, we are going to need a database. In this case, we are going to use Firestore. A Firebase real-time database that will allow us to subscribe to the data, and see changes the moment they are received in the database. We will follow these steps to complete the example.

Activate Firebase in our project. Create fake data for our fake user. Create a login view to authorizing our user. Create a view to show the user data. Create a view to show the user secret messages feed.

Activate Firestore

Now is time to use a Firestore database. So let’s create one.

Let’s create a database.

And click on “create database”.

Click on “Create database”.

The first option you have is, which set of access rules you want. If you are in development mode, maybe you should choose “Start in test mode”, but if you have an authentification layer, you need to “Start in locked mode”, and then modify the access condition.

Lock mode means no access. Later we will need to edit the rules.

So, here it is! Your new and shiny database.

Now it’s time to change the permissions to be able to access it. Just go to the “rules” tab in the upper menu, and change the condition in the code section from “allow read, write: if false;” to “allow read, write: if request.auth.uid != null;”. Then publish the changes.

Every time you launch a petition to the database, the first thing you check is that the “auth” in the request has a valid user id. And the only way to have a valid one is having obtained it after an authentication process, for example, using a login view. The user id must match one of the users already logged.

Create fake data

SO now, return to the “data” tab and start a new collection. We are going to create a users collection to store the basic data of our user. In this case, we can use this fake personal data generator site to obtain all the data we need.

Access here clicking on “+ Add collection”.

After creating it, you can add you first document (this is a NoSQL database, so each entry is a JSON document).

And now, let’s just fill a few fields. Choose the fields you want to have. I will use the email as the document id but you can just add an autogenerated id. The email will be a field of the user, to allow us to find the user by its email. The email will be our unique key to find our user.

And here we have our fake user.

Create a view to show the user data

So now that we have our database up and running, and our fake user data filled up, let’s show it in our application. The starting point will be the previous article where we already logged in into the platform. Using this other article, we are going to create three routes:

Login. User profile. User secret messages feed.

The login route will give the user access using email and password, and the other two will show the user’s data. But don’t worry. We will go step by step and doing things together.

I’m going to use a repository without the Firebase configuration files (you must use your own), and a branch for each article. The main branch will have the hello world, another branch will have the previous article code, and a new branch will have this article code (each branch with its related article name).

Login View

A login view is a simple form. We have two text fields for email and password (already filled up in the example), and a button to log in. The idea here is to authenticate the user and navigate to the user profile. In case the user fails to introduce its email or password, we will tell him that the credentials are wrong, but we are not going to specify whether the email or password, to avoid giving clues to hackers. Try to mess up with the login, and change the user credentials in the input fields.

Login screen.

The warning message will appear because its visibility depends on a variable called “loginError”. While the login error is false, the message will be hidden, and when the login process returns an error, and we set the login error to true, the message will appear on the screen.

Login screen with an error.

I’m going to pass over this because there are other articles about forms. So let’s go to the cool part, and fetch the user data from the database.

User Profile

Because we are using “Firestore”, we have a NoSQL real-time database, and that’s pretty cool because we can use a “StreamBuilder” widget to connect to a certain collection of data under certain conditions, and have a different snapshot of our collection every time the data changes.

The code is pretty simple. We just need to pass a “StreamBuilder” in the body of our view scaffold.

A simple StreamBuilder wrapping our view’s contents.

OK, let try to explain this awesome piece of code.

As you can see, we have wrapped our body with a new widget. This widget is called a “StreamBuilder”, and its purpose is to connect to a stream and serve new data inside its “builder” property. And what is a stream? A stream is a provider of an asynchronous sequence of data. That means that it’s like a Mario Bros pipe, from where from time to time a Koopa pops out. The “StreamBuilder” widget mission is to watch over the stream and give to us everything that appears through it.

“Firestore” will launch a database snapshot every time the data changes, so our widget will give us a new database snapshot with every change, and we will have our data update in real-time on our app.

A simple stream explanation using smiley faces.

And that’s it! Now you can check the app behavior, modifying the data in Firestore and seeing how it changes instantly in the app, having both screens side by side.

And now, you can navigate to the “feed” view and every time you add a new message, it will appear there. You just need to create a new collection called “feed” and add documents with two fields. The user “email”, and the “message”. If you do it correctly, the messages will appear in the feed screen.

Good luck!