I am trying to learn about firestore and its data structure.
I have read that the queries are swallow so if I do a query I don't get the data from the subcollection.
I have an application about shopping, this application has a collection shoppingCart
and this shoppingCart
has a field name
an another collection lists
inside and those lists
have products
with a name
.
If I want to get just the shoppingCart name
in a query and in other query I want to get the lists
inside this shoppingCart
should I structure my data as:
shoppingCart
name
Lists
listId1:
Products:
productId1:
name
and then do a query to get the collection shoppingCart
an another query to get the subcollection lists
.
Or should I duplicate data and do a collection with just the field:
shoppingCart:
name
and then another shoppingCart
with the subcollection lists
shoppingCart:
Lists
listId1:
Products:
productId1:
name
I know it depends a lot in the application, but I am a bit confused, because I read the documentation and doesn't say anything against this, but in the realtime database documentation it says to avoid nested list. I know they are not the same but after reading this I don't know if the nested subcollections are a good practice.
Thank you in advance.
CodePudding user response:
When it comes to storing shopping cart products in Firestore, there are three ways in which you can do this.
- You can create a shopping cart document that can hold product IDs or references that point to documents. In this case, to display the content of the shopping cart, you have to create separate calls for displaying product details. Since a shopping cart, most likely belongs to a user, the schema should look like this:
Firestore-root
|
--- users (collection)
|
--- $uid (document)
|
--- shoppingCart (collection)
|
--- content (document)
|
--- ["productId", "productId"] (array)
The benefit is that if you're using a real-time listener, if an admin changes a price or if a product becomes unavailable, you'll be notified instantly.
- The second option would be to create a shopping cart collection where you can store as documents all items in the cart. This means that when a user clicks the "add to cart" button, then you should copy the product object inside this collection:
Firestore-root
|
--- users (collection)
|
--- $uid (document)
|
--- shoppingCart (collection)
|
--- $productId (document)
|
--- //product fields.
- The third option would be to create a single document that can hold all items, as long as the size of the document doesn't get larger than 1 Mib, which is the maximum limit:
Firestore-root
|
--- users (collection)
|
--- $uid (document)
|
--- shoppingCart (collection)
|
--- content (document)
|
--- items (array)
|
--- 0
|
--- //product fields.
If you're interested, I recently started a series of articles called:
Here is the part responsible for the Firestore schema.
Edit:
In my case the shoppingCart is shared between multiple users.
In that case, it doesn't make sense to add the shopping cart under the User document. It can be a top-level collection or a stand-alone document in a collection of your choice.
so if I add a product to the cart I want the rest of the users to be notified instantly.
In that case, you should create inside the shopping cart document, an array of UIDs. In this way, you'll be able to know to which users to send a notification.
can I do that like in the second option, making that if a new product is added or deleted I notify the users, or should I do it like in the first option?
It's up to you to decide which option to choose. If one of the above solutions, solves the problem, then you can go ahead with it.
if I want to notify the users in real-time, should I duplicate documents like in Realtime Database or should I not duplicate documents?
You should duplicate the data only when needed. That's why I provided three solutions so you can choose which one fits better.