So I am trying to figure out the best structure for my use case.
Currently it looks like this:
salesItems | userId | salesItem1 |
| salesItem2 | and so on.
So the items are stored in a document named with the respective userid.
The problem with this is, that I am expecting this document to get bigger than 1MB.
So I thought maybe I need to setup collection group queries.
Therefore I set up a structure like this:
salesItems | userId | StoreA | documentId | startDate:
| endDate:
| salesItems:
| StoreB | documentId | startDate:
Where items get stored as chunks in a document, which get start- and enddate as fields to make it possible to query these chunks by date.
So a document would look like this:
startDate: 01/01/2021
endDate: 12/31/2021
salesItems:[items]
My goal is to query all documents across all stores for a user.
So my questions are:
After watching fireships tutorial on collection group queries, it seems like there are special security rules needed for collection group queries.
Currently I am writing :
match /salesItems/{userId}/{documents=**} {
allow read, write: if true; //No restriction for testing purposes.
}
but that doesn't work.
Here is a screenshot of the current structure.
NOTE I need to store items in the 2 box. I plan to remove the 1 row, but thats not part of the question.
For a stores and items data, you can try structuring your database as shown below:
users -> {userId}
(col) (doc)
stores -> {storeId} -> items -> {itemId}
(col) (doc) (col) (doc)
You can store a field ownerId
in each store document to reference the user who owns the store (or an array of UIDs if a store can have multiple owners).
This way you can query items from a specific store as well as by item ID of any property in item document using CollectionGroup queries.
I'm not sure about what permissions you required on these collections but for collection group queries you can structure them as shown below:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Allow anyone to read items
match /{path=**}/items/{itemId} {
allow read: if request.auth != null;
}
// Allow users to read but owner to write store
match /stores/{storeId} {
allow write: if request.auth.uid == resource.data.owner;
allow read: if request.auth != null;
}
}
}
Additionally, the items sub-collection can also be a root level collection. Then you would have to add a field that contains storeId in it as well but then there would be no need to use CollectionGroup queries.
Edit:
Since each can have their own data of each store, the following structure can be used:
users -> {userId} -> stores -> {storeId} -> items -> {itemId}
(col) (doc) (col) (doc) (col) (doc)
You now have a store document for each user any information about that store can be stored in the store document. While items
can be an array as mentioned in the original question, it might be easier to to query those if stored in a sub-collection since there isn't any unwind
like functionality in Firestore.