Yingrjimsch
Yingrjimsch

Reputation: 122

How to make the best firestore schema for my case?

I want to make a firestore schema for a little angular app I'm trying to make. My Problem is, that I don't know what schema makes most sense. I try to get good performance and as less queries as possible. My object are as following:

The idea is, that a User has his own settings (like language etc.). He also can create a cardlist to which he can add as many cards as he want. I wanna be able to query all cards by card list, all cardlists by user, all settings by user...

Are there any Suggestions?

Upvotes: 1

Views: 1380

Answers (1)

Alex Mamo
Alex Mamo

Reputation: 138824

A possible database schema for your app might be:

Firestore-root
   |
   --- users (collection)
   |    |
   |    --- uid (document)
   |         |
   |         --- userName: "NameOfUser"
   |         |
   |         --- settings (map)
   |         |    |
   |         |    --- language: "en"
   |         |    |
   |         |    --- //Other settings properties
   |         |
   |         --- //Other user properties
   |
   --- cards (collection)
   |    |
   |    --- cardId (document)
   |         |
   |         --- uid: "uid"
   |         |
   |         --- //Other card properties
   |
   --- decks (collection)
        |
        --- uid (document)
             |
             --- userDecks (collection)
                    |
                    --- deckId (document)
                          |
                          --- deckName: "NameOfTheDeck"
                          |
                          --- //Other deck properties
                          |
                          --- userDeckCards (collection)
                                 |
                                 --- cardId (document)
                                       |
                                       --- uid: "uid"
                                       |
                                       --- //Other card properties

The idea is, that a User has his own settings (like language etc.). He also can create a cardlist to which he can add as many cards as he want. I wanna be able to query all cards by card list, all cardlists by user, all settings by user

Using this database schema, you can simply:

  • Get all users by attaching a listener on users collection reference:

    db.collection("users").get().then(/* ... */);
    
  • Get all settings that correspond to a specific user, using the following reference and iterate over the settings map:

    db.collection("users").doc(uid).get().then(/* ... */);
    
  • Get all cards from all users by attaching a listener on cards collection reference:

    db.collection("cards").get().then(/* ... */);
    
  • Get all cards that correspond to a specific user by using a query:

    db.collection("cards").where("uid", "==", uid).get().then(/* ... */);
    

As you can, only two top-level collections are necessary. For your particular use-case, there is also no need to denormalize data, it will scale without problems.

Edit:

According to your comments, yes, you should create another collection named decks so you can get all the decks that correspond to a specific user. For that, the following collection reference is required:

db.collection("decks").doc(uid).collection("userDecks").get().then(/* ... */);

If you want to get all the cards that correspond to a specific user deck, the following collection reference is collection reference is required:

db.collection("decks").doc(uid)
    .collection("userDecks").doc(deckId)
    .collection("userDeckCards")
    .get().then(/* ... */);

In this case you need to use denormalization. This is a common practice when it comes to Firebase. If you are new to NoQSL databases, I recommend you see this video, Denormalization is normal with the Firebase Database for a better understanding. It is for Firebase realtime database but same rules apply to Cloud Firestore.

Also, when you are duplicating data, there is one thing that need to keep in mind. In the same way you are adding data, you need to maintain it. With other words, if you want to update/detele an item, you need to do it in every place that it exists.

Upvotes: 2

Related Questions