0
votes

Introduction

I have the typical "Interactions" screen where I show an infinite list with the users that have liked/commented in one of my posts and also the ones who has recently sent a new message. This screen is in a Tab Navigator with a "Badged Icon" (which displays the number of new interactions).

Also, I have another stack screen called "Messages" in which I display the number of new chats and a list of chats.

For getting the number of "new interactions" and "new chats", I have thought to simulate a stack (push data and pop data on my Firestore).

Database Structure

For handling this use case, I have thought to structure my database like this:

/ (root)
|
--> /interactions (collection)
|    |--> /userId (document)
|         |--> pendingPostsInteractionsCount (number) <-------- Always increase. Reset to 0 when the user open the "notifications" screen.
|         |--> pendingChatsCount (number) <-------- Always increase. Decrease when the user open an unread chat.
|         |--> /posts (collection)
|         |     |--> /postId (document)
|         |           |--> /likes (collection)
|         |           |     |--> otherUserId (document)
|         |           |          |--> { date: Date }
|         |           |     ...
|         |           |
|         |           |--> /comments (collection)
|         |                 |--> otherUserId (document)
|         |                      |--> { comment: String, date: Date }
|         |                 ...
|         |              
|         |--> /chats // There are no "groups" in my app
|               |--> otherUserId (document)
|                     |--> messages (collection)
|                          |--> messageId (document)
|                                |--> { text: String, date: Date }
|                          ...
|
|--> /posts (collection)
|    |--> /userId (document)
|          |--> /userPosts (collection)
|               |--> postId (document)
|                     |--> { ...postData }
|               ...
|          ...
|           
|--> /users (collection)
      |--> userId (document)
            |--> { ...userData }
      ...

Problem

  1. As I need to display a badged icon, I will have to listen database changes... I have thought to listen the changes in the /interactions/{userId} document, and then, in my client side, if pendingChatsCount or pendingPostsInteractionsCount has changed, update the badged icon.

  2. When the user navigates to the Likes or the Comments screen, he/she will see a list of likes or comments, respectively, for an specified post of an user.

Can these two situations be correctly handled with this structure? Or would it be better to put the comments and likes collections in /posts/{userId}/userPosts/{postId}/ (also, as sub-collections)

Can Firestore performs a "multiple collections query" at once? So that in my "Interactions" screen I can fetch the required data from different collections ordered by date

And if for example, I want to implement a pull-to-refresh in the interactions screen, and combine it with an onSnapshot listener, will this structure be a good option talking about pagination?

In summary, basically what I wonder is if this is a simple and good structure for the operations that I have commented.

Pd: In my case, I have decided to structure the interactions in this way so as not to have to duplicate data in the database, and thus, when I enter the likes screen of a post, I can also reuse the collection "interactions/{userId}/posts/{postId/likes/" to read the data.

I would appreciate some kind of feedback or advice from someone who has experience with Firestore and NoSQL databases in general.

Thank you.

1
If you can make queries to satisfy your app's requirements, then yes, it's good enough. That's all that really matters. If it doesn't satisfy queries, then you will need to step back, define your queries carefully, then structure your data to satisfy them. NoSQL data modeling typically follows the queries you need, so define those first. - Doug Stevenson
Okey, thank you very much, I will follow your advice. I was afraid that it was a somewhat crazy structure or of the style, even having designed them thinking about the consultations to be made... - Victor Molina
However, I will not delete the question in case anyone is interested in this structure or can help them in the future. - Victor Molina

1 Answers

1
votes

Posting this as a Community Wiki, since this was commented by @DougStevenson and it answered the question:

If you can make queries to satisfy your app's requirements, then yes, it's good enough. That's all that really matters. If it doesn't satisfy queries, then you will need to step back, define your queries carefully, then structure your data to satisfy them.

NoSQL data modeling typically follows the queries you need, so define those first.