For people who are new to Firebase, Firebase is a server-less architecture service provided by Google it supports Android, iOS, Web and unity Projects.
The Firebase service includes
- Realtime Database
- CloudFirestore
- Firebase Cloud Messaging
- Analytics
- and more
Here in this tutorial we will learn how to use Cloud Firestore in Flutter Apps.
Before starting please go through this article to Create and integrate new project in Firebase. Flutter, Getting started with Firebase
Introduction
What is Cloud Firestore ?
Cloud Firestore is a NoSql database without any rows or columns all the data are saved as Documents or Collections and subcollections soo on. Where the document is an object and collection is list of the documents(objects). Which can be considered as a big json file mapped together. The Cloud firestore supports Realtime listening to the changes that is happening in the document or collections are even in chained queries.
Adding Firestore to Flutter
Please check this article Flutter, Getting started with Firebase for adding Google Services to the flutter app.
To use firestore add the following dependency to the flutter app
dependencies:
cloud_firestore: ^0.13.5
Run flutter pub get based on your IDE.
Write data to Cloud Firestore
Create a instance of the cloud firestore reference
CollectionReference _fireStore = Firestore.instance.collection('users');
Add data to user collection,
void addUser() {
_fireStore.add({
'userName': 'Leo',
'email': 'leyo@gmail.com',
'phone': 9876543210,
'emailVerified': true,
}).then((document) {
// prints the document id when data adding succeed.
debugPrint(document.documentID);
});
}
The above method will create a random document ID for the added document on the other hand we can add our own document ID as follows
String documentID = _fireStore.document().documentID;
void addUser() {
// this will generate a document ID
String documentID = _fireStore.document().documentID;
// or if you want to add a specific Doc ID for example
// firebase auth User ID
// var firebaseUser = await FirebaseAuth.instance.currentUser();
// documentID = firebaseUser.uid;
_fireStore.document(documentID).setData({
'userName': 'Leo',
'email': 'leyo@gmail.com',
'phone': 9876543210,
'emailVerified': true,
}).then((_) {
// prints the document id when data adding succeed.
debugPrint('added successfully');
});
}
The setData() includes an additional param merge , if merge is set to true it will support both add and update. setDataw with merge true will update the document if already exists or add new one if not.
void addUser() {
// this will generate a document ID
String documentID = _fireStore.document().documentID;
// or if you want to add a specific Doc ID for example
// firebase auth User ID
// var firebaseUser = await FirebaseAuth.instance.currentUser();
// documentID = firebaseUser.uid;
_fireStore.document(documentID).setData({
'userName': 'Leo',
'email': 'leyo@gmail.com',
'phone': 9876543210,
'emailVerified': true,
}, merge: true).then((_) {
// prints the document id when data adding succeed.
debugPrint('added successfully');
});
}
Update Data in Firebase
To update a specific document inside a collection you can do the following, Also while updating you can add a new parameter
Here we are updating the userName and adding new param dob.
void updateUser(String userId) {
String documentID = '$userId';
_fireStore.document(documentID).updateData({
'userName': 'elstin', // userName is updated
'email': 'leyo@gmail.com',
'phone': 9876543210,
'dob' : '21-Aug', // new parameter
},).then((_) {
// prints the document id when data adding succeed.
debugPrint('added successfully');
});
}
Add sub collection to document.
For example you want to add some posts that are specific to the current user, in that case we can create a subcollection to add the posts. The sub collection won’t be retrieved when you call the document collection, If you call the documents from user collection it won’t contain the posts sub collection.
To create a posts sub collection
void addPost() {
// this will generate a document ID
String documentID = _fireStore.document().documentID;
// or if you want to add a specific Doc ID for example
// firebase auth User ID
// var firebaseUser = await FirebaseAuth.instance.currentUser();
// documentID = firebaseUser.uid;
_fireStore.document(documentID).setData({
'userName': 'Leo',
'email': 'leyo@gmail.com',
'phone': 9876543210,
'emailVerified': true,
}, merge: true).then((_) {
// add new post dub collection to the document
_fireStore.document(documentID).collection('posts').add({
'title': 'hey this is a new collection',
'content': 'This is a nes collction content',
});
});
}
Delete data from Firestore
To delete document from the collection we can use the delete() method as follows
void deletePost() {
// this will generate a document ID
String documentID = _fireStore.document().documentID;
// or if you want to add a specific Doc ID for example
// firebase auth User ID
// var firebaseUser = await FirebaseAuth.instance.currentUser();
// documentID = firebaseUser.uid;
_fireStore
.document(documentID)
.collection('posts')
.document('post_id')
.delete()
.then((_) {
// delete success
});
}
The above function will delete the specific post document from the users post collection.
To delete a field from the document we can use FieldValue.delete() with updateData()
void updateUser(String userId) {
String documentID = '$userId';
_fireStore.document(documentID).updateData(
{
'userName': 'elstin', // userName is updated
'email': 'leyo@gmail.com',
'phone': 9876543210,
'dob': '21-Aug', // new parameter
'userVerified' : FieldValue.delete() // deletes the field
},
).then((_) {
// prints the document id when data adding succeed.
debugPrint('added successfully');
});
}
Fetch data from Firestore
To retrieve documents from a collection the getDocuments() method can be used
void getUsers() {
_fireStore.getDocuments().then((QuerySnapshot snapshot) {
snapshot.documents.forEach(
(DocumentSnapshot documentSnapshot) {
// prints all the documents available
// in the collection
debugPrint(documentSnapshot.data.toString());
},
);
});
}
The snapshot.documents will return all the available in the collection as List<DocumentSnapshot>.
Get a Document
To get only on particular from the collection we can use the documentID along with document(<docID>).get() method
void getUserData(String docID) {
_fireStore.document(docID).get().then((DocumentSnapshot snapshot) {
// prints the document Map{}
debugPrint(snapshot.data.toString());
});
}
Listen for Real Time Updates
We can also listen to change of any document in the collection.The real time event will be triggered each and every time update/ delete / addition or any changes happens to the document of the collection.
void listenToChanges() {
_fireStore.snapshots().listen((snapshot) {
// this will be called each and every time
// any changes happens in the collection
snapshot.documents.forEach(
(DocumentSnapshot documentSnapshot) {
// prints all the documents available
// in the collection
debugPrint(documentSnapshot.data.toString());
},
);
});
}
Also the snapshots() method returns a Stream<Queryapshot>, therefore we can listen to the changes happen in realtime and we can use the stream builder to bind the stream directly to the UI
class BookList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: _fireStore.snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError)
return new Text('Error: ${snapshot.error}');
switch (snapshot.connectionState) {
case ConnectionState.waiting: return new Text('Loading...');
default:
return new ListView(
children: snapshot.data.documents.map((DocumentSnapshot document) {
return new ListTile(
title: new Text(document['title']),
subtitle: new Text(document['author']),
);
}).toList(),
);
}
},
);
}
}
I hope you enjoyed the Article. Follow me on Linkedin| Github | Twitter @leoelstin for more articles.
Here is a Open source application I built with CloudFirestore as Backend.