Cloud Firestore is a no-SQL database that stores data in documents that are organized by collections. Each collection can store plenty of documents which store data in fields mapping to values. Moreover, documents can contain sub-collection that in turn consist of various documents. Documents support many data types including strings, numbers, dates, objects, references, etc.
So, how do you write to Firestore in Flutter?
Firebase Firestore provides several ways to write data including adding data to a collection using map, or adding data using custom objects (model classes) which are converted to JSON format.
In this article, we’ll learn how to add data to Firestore in Flutter and understand the difference between set and add functions.
First things first, you’ll need to set up your Firebase project and set up your Flutter app with Firebase.
So, if you’ve done so, let’s jump into our tutorial!
Table of Contents
The difference between set and add functions
Cloud Firestore allows you to add data using two functions, set and add. Both functions work similarly in term of adding data to Firestore.
Set method
The set method overwrites a document with the newly specified data if it already exists. If it doesn’t exist, it will create a new documents with the data you specified. In addition, the set method requires you to specify the document ID that you want to create.
In case you’re note sure whether a document exists, you can pass an option to merge the new data with any existing document to avoid overwriting existing documents.
Example
If you’ve followed the previous tutorial, you’ll find that we created a collection named Users which we’ll also be using in this tutorial. So, make sure to follow the previous tutorial to avoid confusion.
In this example, we’ll create a collection reference to get an instance of the Users collection in our Firestore then create a function setUser() to add the new user to the Users collection.
CollectionReference users = FirebaseFirestore.instance.collection('Users'); Future<void> setUser() { final user = { 'name': 'Sarah', 'email' : 'sarah@gmail.com', 'gender': 'Female', 'age': 35 }; return users.doc('id').set(user).then((value) => print('user is set')) .onError((error, _) => print('Failed to set user: $error')); }
Now, giving the id we gave to the document we want to add, if the document exists then its data will b overwritten. If you want to add the merge option, then you can add the SetOptions(merge: true)
attribute inside the set function as the following:
return users.doc('id').set(user, SetOptions(merge: true)).then((value) => print('user is set')) .onError((error, _) => print('Failed to set user: $error'));
Add method
The add method allows you to create documents with unique auto-generated IDs. Moreover, it makes sure that a new document is created even if a document exists with the same data.
Example
Future<void> addUser() { final user = { 'name': 'Sarah', 'email' : 'sarah@gmail.com', 'gender': 'Female', 'age': 35 }; return users.add(user).then((value) => print('user successfuly added')) .onError((error, _) => print('Failed to add user: $error')); }
You can also create a document reference with an auto-generated ID then use its reference to assign its data later.
//create a document with auto-generated ID final data = <String, dynamic> {}; final newUserRef = users.doc(); //Later newUserRef.set(data);
In this case, set() and .doc().set() are totally equivalent.
Adding data using custom objects
In the previous section, we’ve seen how to add data using a map. The downside of using a map is that it loses the type safety as we may make mistakes when creating the map which will lead to crash in our app. Firestore converts data to JSON format to be type-safe. Besides, JSON is light-weight format, well-structured, and easy to be read by systems. You can use withConverter that comes with dart:convert library. This method allows you to convert data to JSON format and vice versa.
When you want to use this method, you’ll need to work with serializable class. To do so, we’ll create a model class and implement the converter methods to perform the adding function.
Example
In this example, we’ll create a model class (User) and specify the variables for our data fields. Also, we’ll create toJson() method that returns a JSON object that has key-value pairs corresponding to all fields in the class. Then, we’ll create fromJson() method that converts JSON object back to a map.
Creating model class User
import 'package:cloud_firestore/cloud_firestore.dart'; class User { late String name; late String email; late String gender; late int age; User({required this.name, required this.email, required this.gender, required this.age}); Map<String, Object> toJson() { return { 'name': name, 'email': email, 'gender': gender, 'age': age }; } factory User.fromFirestore( DocumentSnapshot<Map<String, dynamic>> snapshot, SnapshotOptions? options, ) { final data = snapshot.data(); return User( name: data?['name'] as String, email: data?['email'] as String, gender: data?['gender'] as String, age: data?['age'] as int ); } }
Implementing the add method
CollectionReference users = FirebaseFirestore.instance.collection('Users'); Future<void> addUser() async { final user = User( name: 'Zain', email : 'zain@gmail.com', gender: 'Male', age: 35 ); final docRef = users.withConverter( fromFirestore: User.fromFirestore, toFirestore: (User user, options) => user.toJson() ); await docRef.add(user); }
Conclusion
This brings an end to our tutorial where we learnt how to add data to firestore in flutter using different methods. We’ve learnt the difference between add() and set() methods and how to implement them. Furthermore, we learnt how to use custom object to manipulate maps and convert them to JSON format and vice versa.
If you wish to learn more about Firebase, I have a whole category of Firebase that’s ripe for you to explore. You can learn about Firebase Email Authentication, mobile authentication, and Facebook authentication.
Also, don’t forget to like and share my Facebook page, share the post with those who care to learn, and subscribe to my blog to be one of the firsts to know about my newest posts!
Thank you and happy coding!