DEV Community

Cover image for How to Use Firestore To Persist Data in Flutter Apps
Anderson Dalbert
Anderson Dalbert

Posted on • Edited on

How to Use Firestore To Persist Data in Flutter Apps

Hello there! The purpose of this arcticle is to be very objective and summarize all about how to access and make the most common queries to Firestore using Flutter, Google's Mobile App SDK.

Table of Contents

Example database

To examplify our tutorial, I'm gonna introduce a sample database which contains a simple collection of cars:

Example database containing data from cars

Basics

You should use Firestore object and call it's instance to access the database from Firestore:

final Firestore database = Firestore.instance;

Now, the database object will get you access to all collections inside your Firestore database.

Getting data

Get a single document

Future<DocumentSnapshot> car = 
    database.collection('cars')
    .document('D3idV9o7uWT4pWvby643')
    .get();

The code above use our database variable to access our collection of cars, by passing its identifier (the collection's name) as argument. Then, we access the document we want to get, passing its unique ID.

This will return a Future<DocumentSnapshot>. A DocumentSnapshot encapsulates all data inside an element from a collection. I suggest that you read its documentation. It will get you more comfortable on how to manipulate the data inside a DocumentSnapshot.

So, since you have a Future object, it means that the DocumentSnapshot inside it only will be returned some moment after the instruction is executed, but you don't know exactly when. To extract the DocumentSnapshot inside it, you can use then method:

car.then( (DocumentSnapshot carSnapshot) => { 
   /* insert here the code of what you want to do with the snapshot*/  
});

Let's say, for example, that you want to access and print the property model from the car:

car.then( (carSnapshot) => { 
   print(carSnapshot["model"]) 
});

/* output is: 
Honda Civic 2.0 LXR
*/

Get a whole collection

To get all snapshots from a collection:

Stream<QuerySnapshot> stream = database.collection("cars").snapshots();

This will return a Stream object. To iterate over the object you got to perform some operations with the data it contains, you may use a StreamBuilder.
Let's say, for example, that you want to show the model and year from each car you have inside your cars collection, displaying it in your app's screen.

...
final Stream<QuerySnapshot> stream = database.collection("cars").snapshots();

@override
  Widget build(BuildContext context) {
    return StreamBuilder<QuerySnapshot>(
      stream: stream,
      builder: (context, snapshot) {
        if (snapshot.hasError) return ErrorDialog("Error while trying to access car data");
        switch (snapshot.connectionState) {
          case ConnectionState.active:
            return Container(
              child: ListView(
                children: List.generate(snapshot.data.documents.length, (index) {
                    DocumentSnapshot currentDocument = snapshot.data.documents[index];
                    return Text(currentDocument["model"] + " " + currentDocument["year"])
              })));

          default: return Text("Loading data");
        }
      }
    );
  }

How to update data

This is how you update data from an document inside our collection of cars:

Future<void> updateData = database
   .collection('cars')
   .document('D3idV9o7uWT4pWvby643')
   .updateData(
      {
      "year": 2020,
      "model": "Toyota Corolla XEI 2.0",
      "hasInsurance": true
      });

If you want to update just one field, the query is just the same. You just have to pass only the field you want to update. For example:

Future<void> updateOneField = database
   .collection('cars')
   .document('D3idV9o7uWT4pWvby643')
   .updateData(
      {
      "hasInsurance": false
      });

How to insert data

Use setData method, which creates a new document by passing the ID you want the document to have.

Future<void> insertData = database
   .collection("cars")
   .document("nVnAIom5wFBPL4h88w7D")
   .setData(
     {
     "model": "Tesla Model X",
     "year": 2019,
     "hasInsurance": true
     });

This will create a new element inside our cars collection. Just remember that, if there is already a document with same ID, it will get overrided. So, it may be a good idea to check if there is already a document with the ID you want to create before using setData.
For doing so, you just have to perform a get (which you already know how to do by now) passing the ID you want to check. Then, verify if it returned a snapshot by using exists method. For example:

final docSnapshot = await database.collection('cars').document('nVnAIom5wFBPL4h88w7D').get();
if ( !docSnapshot.exists) {
   // insert logic to add a new document goes here
}

That's it, folks! With what you learned, I'm sure you will be able to get a lot o stuff done with Flutter and Firestore.

Hope that helps!

Top comments (0)