1

I'm building a react native app with redux, react-redux, redux-thunk, and using firebase as a backend.

My database is denormalized, so I've to fetch keys in a firebase reference and for each key I need to fetch data from another reference.

Using firebase .once('value') I got something like this:

const fetchPosts = ( uid ) => {
    return ( dispatch ) => {

         dispatch(postsIsFetching())

         const userPostsRef = firebase.database().ref('users/' + uid + '/myposts')

         var keys = []
         //
         userPostsRef.once('value').then(snap => {

             snap.forEach(post => keys.push(post.key))

         }).then(() => {

         keys.forEach(key => {

             const postRef = firebase.database().ref('posts/' + key )

             postRef.once('value').then(snap => {
                 var newPost = {
                            title: snap.val().title,
                            user: snap.val().user
                            }
                 dispatch(setPost(newPost))
             })

        })

     }
}

But that's not realtime updating, cause the .once() method read data once only. The .on() method doesn't return a Promise, so how could I fix that? What's the best pattern to fetch data with redux-thunk and a denormalized firebase database?

Thanks guys

Dario Ielardi
  • 807
  • 9
  • 24

1 Answers1

0

Put the code you'd normally put in a .then() inside the .on() callback. This way, every time the data refreshes, your setPost action will be dispatched.

For example:

...
postRef.on('value', snap => {
    var newPost = {
        title: snap.val().title,
        user: snap.val().user
    }
    dispatch(setPost(newPost))
});

You probably want to hold on to that database reference so that you can stop listening later.

Jeff
  • 2,425
  • 1
  • 18
  • 43
  • Thanks a lot Jeff, but the problem is that I should fetch posts key in the reference 'user/myposts', so I should change something at the first .once(). – Dario Ielardi Apr 29 '17 at 01:16
  • Sure, similar thing applies. Use .on('value', ...) instead of .once(), and instead of using a .then(), just pass the function in as the second argument to .on() – Jeff May 01 '17 at 15:34
  • Okay Jeff, thanks again, now posts are fetched, but something weird happens. I click on fab and the navigator takes me to the 'add post' view. Added the new post I go back to 'my-posts' view, and the issues are: although I told redux to empty 'my-posts' array this is not done, and in addition to the old posts list's element there is every posts ( even the new one ) but double! For example, if I got 5 posts and I add one, when I go back to 'my-posts' list there are 17 posts, the old 5 and the new list ( with 6 elements ) repeated once, so 12 elements. – Dario Ielardi May 10 '17 at 17:34
  • Now I rewrite the thunk and seems like trips are fetched properly, redux store is updated, but none happen on my device. 'my-posts' view is empty. – Dario Ielardi May 10 '17 at 18:00
  • Check out this answer: http://stackoverflow.com/a/32137978/4816918 Outside of that, I won't be able to diagnose this unless you share some code / the structure of your state. Since we've solved the original Firebase issue, this may be worth a new StackOverflow question. – Jeff May 10 '17 at 20:16