firebasegoogle-cloud-platformgoogle-cloud-firestorefirebase-realtime-database

Listening to realtime changes to objects stored in a Firestore Document


I am moving my app from Realtime Database (RTDB) to Firestore. I have some questions regarding structuring data for some objects. In Realtime Database, we could essentially listen to real-time changes at any level but in Firestore, we can only listen to real-time changes in a collection or a document. For example, I have the following data in RTDB

enter image description here

The images object contains the user's profile image. This image can be seen by the user in their profile and also as the contact image for users who have this user as a contact. When the image is updated by the user, the contact image is updated automatically. So, we listen to changes to the image object and update the images when it changes.

While moving it to Firestore, I copied it over as follows:

enter image description here

But now I am not able to only listen to changes to the images object and update the contact image. Rather, I have to listen to changes to the whole userInfo object and update images when there is any change to the userInfo object. The userInfo object tracks a bunch of things, so the change handler will be called many times.

I am thinking that I should probably store the images as a top-level collection, and store images for each user and listen to the images document for the user. I wanted to know if that is a better approach to storing images and if there is a general guideline to store objects that a client needs to listen to in a Firestore document. There are many such objects that may change in real time which were working fine in the below data model in RTDB but proving to be challenging in Firestore.


Solution

  • Since I can't listen to changes to an object within a Firestore document, I am trying to find out what is the best approach in general to handle such cases data-model-wise.

    Yes, that is correct. You cannot get only a slice of a document, that's not possible using the web or mobile client SDKs. Firebase listeners fire on the document level, so you can read the entire document or nothing.

    The best option that you have, in such cases, is to denormalize the data. This means that you can store the images in a separate collection or sub-collection in Firestore, or you can save the same denormalized data in the Realtime Database. The latter would be the preferred solution as it provides the ability to attach a listener and get real-time updates only from a specific part of your data.