5

I am making an app and I am trying to figure out why using nested collections is frowned upon by Firestore. The app is a expense tracking app and the data is only relevant to the logged in user and that user never cares about any other user. There are two ways that I have found to structure the data. One uses a few more levels of nesting than the other. The following structures mean:

collectionName: valueNames
    subcollectionName: valueName

Structure 1 (Not as nested):

user:
    month: totalSpent, startDate, endDate
    transactions: categoryId, amount, timestamp
    categories: monthId, name, totalSpent

Structure 2 (More nested):

user:
    month: totalSpent, name, startDate, endDate
        categories: name, totalSpent
            transactions: categoryName, amount, timestamp

Can someone tell me the advantages of structure 1 as opposed to structure 2? Considering structure 2 seems to be easier to query and I do not have to keep track of multiple id's I can just get the sub collection. This would also make it easier to track previous months to show the user later when they want to analyze their spending.

Zach Starnes
  • 3,108
  • 9
  • 39
  • 63
  • Who told you that it is frowned on? –  Jun 23 '18 at 13:39
  • I placed the link in the question where they said it was not good to do – Zach Starnes Jun 23 '18 at 13:40
  • The link you provided points to documentation for the Firebase Realtime Database, not for Cloud Firestore. While both are NoSQL databases inside Firebase, the two databases are quite different when it comes to data modeling. Which one are you using? – Frank van Puffelen Jun 23 '18 at 14:22
  • @FrankvanPuffelen I am using cloud firestore. – Zach Starnes Jun 23 '18 at 14:25
  • I guess I could place the transactions and the categories under the month as root collections. – Zach Starnes Jun 23 '18 at 14:28
  • 2
    If you're using Cloud Firestore, the recommendations in the documentation of the Firebase Realtime Database are meaningless, so I'd remove that from your question. In your sample data structure, please indicate what collections you have (vs what are nested fields). Also note that it's easier to answer if you show actual code for us to reason over. – Frank van Puffelen Jun 23 '18 at 15:31

2 Answers2

3

Structure 1 allows you to view transactions and categories across multiple months. You cannot query across subcollections (see Is it possible to query multiple document sub-collections in Cloud Firestore?) and so with Structure 2 you would not be able to query all transactions across months or categories.

Explained

With Structure 2 you would need to query the months first, then pick a single month and query the categories within that month, then pick a category (or iterate over each one) and query for the transactions in that category. To aggregate category spending for the year you would need to make 12 calls, one for each month.

With Structure 1 you could query all transactions, limit by date range, limit by category, or a combination of the above. You could query all categories for the year in one go to sum the values for a year overview. Structure 1 gives you a lot more performant queries.

Summary

Remember, Firestore is not like Firebase Realtime Database where you can select all the data in a given tree structure at once. You will need to make a query at each level of the tree (each collection) to pull data.

Jacob Wright
  • 311
  • 2
  • 10
  • 6
    Now that collection group queries are available in Firestore, these structures are mostly equivalent. See https://stackoverflow.com/a/46573167/6253640 for more details. – Gil Gilbert May 07 '19 at 18:55
3

There is nothing wrong in creating those collections as long as you remember to delete them with the actual document. In short deleting a document does not delete the subcollection it contains. This is how it works:

Each document in cloud firestore contains reference or path to the subcollections within it (not the whole subcollection), so when you delete a document, every field gets deleted including the field that stored the reference. Mean while the actual subcollection now lies in the form of garbage which you cannot access because you deleted it's path reference.

Subcollections are actually an improvement over the natural json data flow, but since cloud firestore is in beta version, some of the features (like deleting the subcollections along with documents) may be released when it graduated from beta or later on.

Main advantage of using subcollections is that you save user's data because when you query the document data, subcollection data is not fetched ie. queries are shallow.

itsam
  • 301
  • 2
  • 10