1
votes

I am using Firebase Realtime Database. I have an object which has all the posts created by all our users. This object is huge.

In order to display the posts in a fast way, we have given each user an object with relevant post IDs.

The structure looks like this:

/allPosts/$postID/
          : { $postID: {id: $postID, details: '', title: '', timestamp: ''} }

/user/$userID/postsRelevantToThisUser/
              : { $postID: {id: $postID} }

'postsRelevantToThisUser' only contains the IDs of the posts. I need to iterate over each of these IDs and retrieve the entire post information from /allPosts/

As a result, the client won't have to download the entire allPosts object and the app will be much faster.

To do this, I've written the below code. It is successfully retrieving and rendering only the relevant posts. Whenever a new postID is added or removed from /postsRelevantToThisUser/ in Firebase Realtime Database, React Native correctly re-renders the list.

However, when anything in /allPosts/$postID changes, for exampe: if title parameter changes, it is not reflected in the view.

What's a good way to solve this problem?

let userPostRef = firebase.database().ref(`/users/${uid}/postsRelevantToThisUser`)

      userPostRef.on('value', (snapshot) => {
        let relPostIds = [];
        let posts = [];

        snapshot.forEach(function(childSnapshot) {
          const {id} = childSnapshot.val();
          relPostIds.push(id);
        })

        relPostIds.map(postId => {
          firebase.database().ref(`allPosts/${postId}`).on('value', (postSnapshot) => {
            let post  = postSnapshot.val()
            posts.push(post);
            this.setState({ postsToRender:posts });
          })

})

1

1 Answers

0
votes

Since you've spread the data that you need to show the posts to the user over multiple places, you will need to keep listeners attached to multiple places if you want to get realtime updates about that data.

So to listen for title updates, you'll need to keep a listener to each /allPosts/$postID that the user can currently see. While it can be a bit finicky in code to keep track of all those listeners, they are actually quite efficient for Firebase itself, so performance should be fine up to a few dozen listeners at least (and it seems unlikely a user will be actively reading more post titles at once).

Alternatively, you can duplicate the information that you want to show in the list view, under each user's /user/$userID/postsRelevantToThisUser nodes. That way you're duplicating more data, but won't need the additional listeners.

Either approach is fine, but I have a personal preference for the latter, as it keeps the code that reads the data (which is the most critical for scalability) simpler.