Shivam Goyal
Posted on March 25, 2020
Cloud Firestore is a flexible, scalable database for mobile, web, and server development from Firebase and Google Cloud Platform. Like Firebase Realtime Database, it keeps your data in-sync across client apps through realtime listeners and offers offline support for mobile and web so you can build responsive apps that work regardless of network latency or Internet connectivity. Cloud Firestore also offers seamless integration with other Firebase and Google Cloud Platform products, including Cloud Functions.
What you’ll build?
In this tutorial, you’ll build a mobile app featuring realtime Cloud Firestore Database using the Flutter SDK. Your app will:
- Display a voting interface connected to a Firestore database.
- Update the database on the cloud as you tap on a particular vote.
This tutorial focuses on adding Cloud Firestore to a Flutter app. Non-relevant concepts and code blocks are glossed over and are provided for you to simply copy and paste.
Package Used | cloud_firestore
Setting up Flutter on your machine
The detailed steps to install Flutter on your personal computer & getting started with Flutter is available at the following blog post here.
Adding Firebase to your Flutter App
This tutorial requires already setup Firebase. The detailed steps to integrate Firebase with Flutter is available at the following blog post here.
Your Firebase-Flutter setup is finished, and you’re ready to start building your app!
Create your Cloud Firestore database
You’ll start by setting up Cloud Firestore and initializing it with some values.
- Open the Firebase console, then select the Firebase project that you created during setup.
- From the left nav Develop section, select Database.
- In the Cloud Firestore pane, click Create database.
- In the Secure rules for Cloud Firestore dialog, select Start in test mode, then click Next. On the next screen, select Cloud Firestore location. I suggest selecting
nam5 (us-central)
. However, you can select according to your preference. - Test mode allows any user to read and write to your database, which is convenient during development. However, this can be a security risk. Before releasing an app to production, you should add security rules.
- Our database will have one collection, that we’ll name “candidate”. In the collection is where the names and votes are stored. Click Start Collection, set the collection’s ID to
candidate
, then click Next.
- You can now add documents to your collection. Each document has a Document ID, and we’ll need to have name and votes fields.
- Enter a candidate name using all lowercase letters. In this example, we used
tom
.Using an actual candidate name for each Document ID ensures that the documents are displayed alphabetically by candidate name. By default, Document IDs are auto-generated timestamps, and documents are displayed in the order that they were created.
- For the existing Field, enter the value of
name
, selectstring
for the Type, then enter the Value ofTom
. - Click the Add Field icon to add a second field to contain the number of
votes
. Selectnumber
for the Type, then initialize the Value as0
. - Click Save.
- Add additional baby names by clicking Add Document.After adding several documents to your collection, your database should look something like this:
Coding the application
Add Cloud Firestore plugin to your app
- From the root directory of your Flutter app, open your
pubspec.yaml
file. - Add the FlutterFire plugin for the Cloud Firestore. All Flutter apps with Cloud Firestore, both iOS and Android versions, require the
cloud_firestore
plugin.
- Run
flutter packages get
.
Adding the User Interface
- Using your IDE or editor, open
lib/main.dart
. This file currently contains the entire code for the default Flutter app. - Delete all of the code in
main.dart
, then replace it with the following:
- Save the file, then hot-reload your app. You should see the following app:
- The app is currently just a mock. Clicking on names only prints to the console. The next step is to connect this app to Cloud Firestore. Before doing that, you can read about how the code in
main.dart
is structured.
The first half of this program is fairly straightforward:
- You imported
cloud_firestore.dart,
a plugin for communicating with the Cloud Firestore. - You added some dummy data (soon to be replaced by a Cloud Firestore instance).
- You set the app’s title to Voting Panel.
The interesting part of the code is in _MyHomePageState
. The build
method in this block defines the widget hierarchy that Flutter uses to create the display for your app.
- The app has an
AppBar
(with a title of Voting Panel). - The app’s body contains a
ListView
, which renders each of the dummy data points as individual list items.
The longest method by far is _buildListItem
, which tells Flutter how to build each item in the list (displayed as the rounded rectangles with candidate names and the number of votes).
Lastly, you have Record
, the convenience class that holds a single record for a name. You don't strictly need this class for a simple app like this to function, but it makes the code a bit cleaner.
Connect your Flutter app to Cloud Firestore
Our app is now connected to Cloud Firestore! It’s time to fetch our collection (candidate
) and use it instead of our dummySnapshot
object.
From Dart, you get the reference to Cloud Firestore by calling Firestore.instance
. Specifically for our collection of baby names, call Firestore.instance.collection('candidate').snapshots()
to return a stream
of snapshots.
Let’s plug that stream of data into our Flutter UI using a StreamBuilder
widget.
- In your IDE or editor, open
lib/main.dart
, then find the_buildBody
method. - Replace the entire method with the following code:
- The code that you just copy-pasted has a type error. It’s trying to pass a list of
DocumentSnapshot
to a method that expects something else. Find_buildList
and change its signature to this:
Widget _buildList(BuildContext context, List<DocumentSnapshot> snapshot) {
...
- Instead of a list of
Map
, it now takes a list ofDocumentSnapshot
. - We’re almost there. The method
_buildListItem
still thinks it's getting aMap
. Find the start of the method, then replace it with this:
Widget _buildListItem(BuildContext context, DocumentSnapshot data) {
final record = Record.fromSnapshot(data);
- Instead of a
Map
, you're now taking aDocumentSnapshot
, and using theRecord.fromSnapshot()
named constructor to build theRecord
. Remove thedummySnapshot
field from the top oflib/main.dart
. It's not needed anymore. - Save the file, then hot-reload your app. After about a second, your app should look like this:
You’ve just read from the database that you created! If you want, you can go to the Firebase console and change the database. Your app will reflect the changes almost immediately (after all Cloud Firestore is a real-time database!).
Add interactivity
Next, you will allow users to actually vote!
- In
lib/main.dart
, find the line that saysonTap: () => print(record)
. Change it to this:
onTap: () => record.reference.updateData({'votes': record.votes+1})
Instead of just printing the record to the console, this new line updates the baby name’s database reference by incrementing the vote count by one.
- Save the file, then hot-reload your app.
Voting is now functional, including the update to the user interface.
How does this work?
When the user taps the tile containing a name, you are telling Cloud Firestore to update the data of that reference. In turn, this causes Cloud Firestore to notify all listeners with the updated snapshot. As your app is listening through theStreamBuilder
implemented above, it's updated with the new data.
Here are the final contents of lib/main.dart
.
Building & running the application
- Connect your Emulator or physical Android device to test the application.
- Click on Build & Run.
- And Boooom 🔥, your app is ready.The final build would look like the below illustration.
🎯 That’s all for today.
If you got any queries hit me up in the comments or ping me over on hi@itsshivam.com 📧
If you learned even a thing or two, clap your hands👏 as many times as you can to show your support! It really motivates me to contribute towards the community.
Feeling too generous? Buy me a Drink 🍺
Wanna collaborate? Let’s talk some tech 😊
Stalk me over on itsshivam.com, GitHub, or LinkedIn. 👀
This article was originally published at Enappd.
Posted on March 25, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.