Flutterexperts

Empowering Vision with FlutterExperts' Expertise
Firestore Subcollections In Flutter

Firebase is an amazing platform developed by Google to connect mobile and web applications and help developers to improve, build, and grow their apps. Firebase provides us a variety of products Authentication, Realtime Database, Cloud Firestore, Cloud Storage, Cloud Functions, Firebase Hosting, ML Kit. Firebase is highly effective and easy to use.

Firebase cloud firestore is a flexible and scalable database. It offers offline availability of data across your client’s apps and keeps data in-sync across clients apps through realtime listeners.

In this blog, we shall discuss how to work with cloud firestore subcollections:


Table of contents:

::What is subcollection?

::Connecting app to your firebase project

::Creating users collection

::Creating a sub collection

::Fetching a sub collection

::Updating sub collection

::Deleting sub collection


To work with firebase cloud firestore in flutter you need to learn about basic crud operation i.e. uploading data, deleting data, editing data, fetching data.

Using Firebase Firestore in Flutter
Fetching data from cloud firestoremedium.com

What is subcollection?

Let’s understand subcollection through an example, take an example of a shopping application, in this app, there are two people 1st the user that will place the order and the 2nd wander that will accept the user’s orders. For each user, the wander needs to keep a record of every user’s order. So to keep the data in a sequential manner we can create a subcollection in the following manner.

***Subcollection example***

In the above image, you can easily analyze the user’s order in an easier and precise manner. So to create this type of collection we need to specify the documentId .

Why the documentIdis important?

Assigning a specific documentId is very important if you are building two different applications one for the user and the other for a wander. To fetch all the orders with the user’s details we need to get all the documentIdof all orders placed by different users inside our wanders application. So to get that documentId we need to fetch it from the users collection that I have created.

Let me explain to you the whole cycle of getting that documentId :

  1. At the time of user authentication auserId is generated by the firebase, we will use this userId and upload it along with user information on cloud firestore inside a users collection.
await FirebaseFirestore.instance
.collection('users')
.doc(userCredential.user.uid)
.set({
'username': username,
'email': email,
'laundryBagNo': laundryBagNo,
'image_url': url,
'userId': userCredential.user.uid //this_one
});

2. Now in the other application we will fetch the stream of users and using the snapshot of the stream we will get all the userId i.e.

‘userId’: userCredential.user.uid //this_one

StreamBuilder(
stream:
FirebaseFirestore.instance.collection('users').snapshots(),
builder: (context, userSnapshot) {
return userSnapshot.hasData
? ListView.builder(
itemCount: userSnapshot.data.documents.length,
itemBuilder: (context, index) {
DocumentSnapshot userData =
userSnapshot.data.documents[index];
if (userData
.data()['laundryBagNo']
.toString()
.startsWith('B-') &&
boys)
return UserCard(
userId: userData.data()['userId'],
userEmail: userData.data()['email'],
userName: userData.data()['username'],
userLaundryBagNo:
userData.data()['laundryBagNo'],
userImageUrl: userData.data()['image_url']);
else if (userData
.data()['laundryBagNo']
.toString()
.startsWith('G-') &&
girls)
return UserCard(
userId: userData.data()['userId'],
userEmail: userData.data()['email'],
userName: userData.data()['username'],
userLaundryBagNo:
userData.data()['laundryBagNo'],
userImageUrl: userData.data()['image_url']);
else
return SizedBox();
})
: CircularProgressIndicator();
},
),

Now we can access the subcollection that we have created named order and we use this id to get all the users and orders.

***Uploading user data on cloud firestore inside users collection***
***Uploading user orders inside orders collection using userId as document id***
***User order documents inside the user_orders sub collection***

Connecting app to your firebase project:

If you are new to firebase then you can follow the steps that I have mentioned in my crud operation blog to connect your apps to Firebase, you can add more then one app to your firebase project:

Using Firebase Firestore in Flutter
Fetching data from cloud firestoremedium.com

Creating users collection:

As we have discussed above, we need a users collection that will store the userId and other users information. We will create this collection when the user signs up.

await FirebaseFirestore.instance
.collection('users')
.doc(userCredential.user.uid)
.set({
'username': username,
'email': email,
'laundryBagNo': laundryBagNo,
'image_url': url,
'userId': userCredential.user.uid
});

Here users is a collection that contains a document whose id is userId i.e. userCredential.user.uid .

Creating a sub-collection:

orders is a collection that contains a document whose id is the userId that we can easily get through FirebaseAuth instance using currentUser.

User user = FirebaseAuth.instance.currentUser; , inside this document, we will create another collection user_orders . user_orders is our sub-collection.

await FirebaseFirestore
.instance
.collection('orders')
.doc(user.uid)
.collection(
"user_orders")
.add({
//add your data that you want to upload
});

Fetching a sub-collection:

To fetch orders subcollection we will need the documentId , so to get the documentId we need to fetch the users collection to get the userId .

StreamBuilder(
stream:
FirebaseFirestore.instance.collection('users').snapshots(),
builder: (context, userSnapshot) {
return userSnapshot.hasData
? ListView.builder(
itemCount: userSnapshot.data.documents.length,
itemBuilder: (context, index) {
DocumentSnapshot userData =
userSnapshot.data.documents[index];
if (userData
.data()['laundryBagNo']
.toString()
.startsWith('B-') &&
boys)
return UserCard(
userId: userData.data()['userId'],
userEmail: userData.data()['email'],
userName: userData.data()['username'],
userLaundryBagNo:
userData.data()['laundryBagNo'],
userImageUrl: userData.data()['image_url']);
else if (userData
.data()['laundryBagNo']
.toString()
.startsWith('G-') &&
girls)
return UserCard(
userId: userData.data()['userId'],
userEmail: userData.data()['email'],
userName: userData.data()['username'],
userLaundryBagNo:
userData.data()['laundryBagNo'],
userImageUrl: userData.data()['image_url']);
else
return SizedBox();
})
: CircularProgressIndicator();
},
)

UserCard is a widget that displays the user details and on taping it new screen is pushed that contains all the orders of that particular user.

Now we will use the userId to fetch the sub-collection.

class CurrentOrders extends StatelessWidget {
final String userId;

CurrentOrders({
@required this.userId,
});

@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: FirebaseFirestore.instance
.collection('orders')
.doc(userId)
.collection('user_orders')
.snapshots(),
builder: (context, orderSnapshot) {
return orderSnapshot.hasData
? ListView.builder(
itemCount: orderSnapshot.data.documents.length,
itemBuilder: (context, index) {
DocumentSnapshot orderData =
orderSnapshot.data.documents[index];
return OrderItem();
},
)
: CircularProgressIndicator();
});
}
}

Updating sub-collection:

FirebaseFirestore.instance
.collection('orders')
.doc(userId)
.collection('user_orders')
.doc(orderData.id)
.update(
{'key': 'new_value'});

Deleting sub-collection:

FirebaseFirestore.instance
.collection('orders')
.doc(userId)
.collection('user_orders')
.doc(orderData.id)
.delete();

Thanks for reading this article ❤

If I got something wrong? Let me know in the comments. I would love to improve.

Clap 👏 If this article helps you.

If we got something wrong? Let me know in the comments. we would love to improve.


Feel free to connect with us:
And read more articles from FlutterDevs.com

FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire a flutter developer for your cross-platform Flutter mobile app project on an hourly or full-time basis as per your requirement! You can connect with us on Facebook, GitHub, and Twitter for any flutter related queries.

We welcome feedback and hope that you share what you’re working on using #Flutter. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences!

Thank you for reading. 🌸

Leave comment

Your email address will not be published. Required fields are marked with *.