0

I am having trouble transitioning from Realtime Database to Cloud Firestore. I'm developing something like a story book app. So, I need to store Stories in my database. Each story contains a set of chapters, and each chapter contains a set of pages.

Back in Realtime Database I used to have a data structure in the likes of:

stories:
    storyId:
        title: "Isaac, the Toothless Dog"
        description: "Isaac wanders Paris seeking for true love."
        chapters:
            title: "Into the Sewers"
            published: true
            chapterId:
                pages:
                    pageId:
                        loose: false
                        occupied: false
                        body: "This is where the body of the page goes"

With Realtime Database I could just request the node storyId, and receive the whole map below with chapters and pages. With that map, in Dart, I would generate an object Story with all that information. That's what I want to achieve, using Cloud Firestore.

For Cloud Firestore, I have designed the following data structure:

enter image description here

Of course, the purple outter boxes represent Collections, and the blue inner boxes represent Documents. I use three dots (...) to show that there would be plenty more documents like the one next to it.

I like this data structure. It looks neat and clean, and I always know what I'm looking at.

However, Cloud Firestore queries are Shallow (a feature I actually like, serves me well in other points of the app), meaning I can only query from a single Collection. That means I can't generate that Story object (in Dart) without, at least, three queries to Firebase.

My question is: Is there a way to achieve this using only one query? If not, is there any way I can organize my data in order to achieve so?

I know I could put the pages and chapters information inside the Stories Collection (like what I had in Realtime Databse), but Documents have a size limit of 1Mb and 20000 fields. If a story contains multiple chapters, each one with multiple pages, that limit may very well be exceeded. That's why I want to keep them in separated Collections.

Any ideas? Thank you.

Alcachofra
  • 135
  • 1
  • 1
  • 6
  • 1
    If your goal is to reduce the number of queries in the Firestore, why dont you add the chapter and story information fields inside the Pages collection and you can query for this information. Can you share what is the sample data that you hold in the body field of page ? Is it plain text or html ? – Vaidhy Dec 08 '21 at 13:25
  • That may be a great idea, actually. I'm used to relational databases, where duplicate data is almost religiously forbidden. But in the **NoSQL** world that seems to be the good practice in some cases. The only problem is that when the title field of the **Chapter** updates (for example), I will have to change it everywhere. That's what I don't like about this approach. Thanks for the great suggestion! – Alcachofra Dec 08 '21 at 13:59
  • If you're new to NoSQL databases coming from a background in relational databases, I recommend reading [NoSQL data modeling](https://highlyscalable.wordpress.com/2012/03/01/nosql-data-modeling-techniques/) and watching [Getting to know Cloud Firestore](https://firestore.video). For your last comment: consider how frequently the chapter titles are updated vs how often they are read. If data changes frequently, it may be worth not duplicating it and performing the extra reads, but only you can answer whether that's the case for your use-case. – Frank van Puffelen Dec 08 '21 at 15:17
  • @Vaidhy That sounds like the start of a great answer! – Frank van Puffelen Dec 08 '21 at 15:18
  • The title will rarely be changed, you are right. I will try this approach, thank you both for pointing me in the right direction. – Alcachofra Dec 09 '21 at 09:46

0 Answers0