react-redux-firebase icon indicating copy to clipboard operation
react-redux-firebase copied to clipboard

feat(populate): populated items update when changed in database

Open DeividasK opened this issue 7 years ago • 21 comments

Original data:

goals: {
  goalId1: {
    uid: 'userId',
    partner: 'userId2'
  }
}
users: {
  userId: {
    displayName: 'John Smith'
  },
  userId2: {
    displayName: 'Jim Rogers'
  }
}

Data after population:

goals: {
  goalId1: {
    uid: {
      displayName: 'John Smith'
    },
    partner: {
      displayName: 'Jim Rogers'
    }
  }
}

I have noticed that after updating the original users.userId.displayName to Batman, the populated item did not update, i.e. goals.goalId1.uid.displayName remained John Smith. I think this is a good default behaviour, but it took me sometime to figure this one out. Maybe this should be mentioned somewhere in the docs?

DeividasK avatar Feb 21 '17 11:02 DeividasK

Correct @DeividasK, populates are only once calls. The original query is most likely on (unless you provided type: 'once'), so updates in that will trigger updates. That means that populate data (i.e. user object) doesn't update when it updates.

I will add something to the docs to outline this, but it brings up the point that it might be nice to turn on this capability. It wouldn't be the default, as you mentioned, since that could potentially cause a huge amount of listeners to be set.

prescottprue avatar Feb 21 '17 17:02 prescottprue

@prescottprue being able to turn this sounds like a great possible enhancement :)

DeividasK avatar Feb 22 '17 05:02 DeividasK

This has been added to the roadmap for v1.4.0.

prescottprue avatar Feb 25 '17 00:02 prescottprue

While we wait for v1.4.0, is there a way to explicitly reload a populated item (or any other data loaded without binding)?

marekolszewski avatar Apr 12 '17 03:04 marekolszewski

@marekolszewski Not currently.

Also, the roadmap is actually going to be updated to reflect that this will not be supported until an even later version (as v1.4.0 ended up being quite large with react-native bugs/features). Will continue to update this issue thread with relevant info.

prescottprue avatar Apr 12 '17 05:04 prescottprue

Getting more and more users asking for this feature. Will hopefully be the big feature of v1.5.0.

prescottprue avatar May 05 '17 08:05 prescottprue

Is this gonna be part of 2.0 or..? :)

projoneftw avatar Jun 24 '17 13:06 projoneftw

@projoneftw That is most likely going to be the plan. I will be reviewing and updating the roadmap this weekend to reflect recent v2 changes (as well as in which versions features such as this one will land).

prescottprue avatar Jun 24 '17 17:06 prescottprue

@prescottprue I'm new to Firebase, but I think it's just changing the once at https://github.com/prescottprue/react-redux-firebase/blob/master/src/utils/populate.js#L84, right?

projoneftw avatar Jun 25 '17 18:06 projoneftw

@projoneftw It is not necessarily just that because a listener is created for each child (part of why it is a callback for '.on('value' listeners and not a promise). Those listeners will need to be tracked and shut off when relevant.

It shouldn't be too "difficult" to do with respect to code, it is more so that there is the possibility for it to use tons of resources done with huge data sets. I will want to include a section in the docs explaining how it could potentially impact an application.

This should definitely make it into v2 though, at least as an option.

prescottprue avatar Jun 26 '17 05:06 prescottprue

@prescottprue wanted to check if there is any update on this? Is it still on track for 2.0?

Also is there any way for force a populate?

raghavendracs avatar Oct 03 '17 10:10 raghavendracs

@raghavendracs Yes, this is still planned for v2.

Not sure what you mean by "force a populate".

prescottprue avatar Oct 03 '17 15:10 prescottprue

Ok thanks.

At the time of loading a component there might be a set of keys which have been populated. Due to actions in the application I am firing some firebase cloud functions which do one of two possible things

  1. Add some keys and associated data
  2. Change data that was populated earlier during loading.

While I know that data has changed in firebase is it also possible for me have react-redux-firebase trigger an update of the Firebase state?

So in my understanding there would probably be no listeners but front end trigger a repopulate.

raghavendracs avatar Oct 03 '17 15:10 raghavendracs

@raghavendracs No there isn't. That is in essence what a listener would be doing.

You could create your own listener, but guessing that it is a unique path of some kind.

There is some people that have been asking for this in person as well, so it is very well known that this feature is needed.

prescottprue avatar Oct 03 '17 15:10 prescottprue

Ok thanks. Will wait for the feature in v2.0

Was only checking in the hope that a complete refresh of the Firebase state on request (without differentiating between keys which have changed and ones that haven't) might have been possible.

raghavendracs avatar Oct 03 '17 15:10 raghavendracs

Wondering if this in in yet? Would be great to use!

Jonovono avatar Dec 05 '17 19:12 Jonovono

@Jonovono This is not in yet. The difficultly is around making sure we correctly track listeners that are created.

When using once queries are not left open, making tracking not too difficult. Open queries are a little more complex.

Really hoping to get the time to get this in, but not sure of a timeline. Open to PRs if anyone has the time.

prescottprue avatar Dec 10 '17 19:12 prescottprue

I'm just wondering about the state of this functionality. Is this still planned or even already solved in some way?

multimulti avatar Aug 09 '18 19:08 multimulti

@multimulti It is not currently supported through populate, but you can do multiple levels of firebaseConnect and connect like so:

import { get } from 'lodash'

compose(
  firebaseConnect(() => [{ path: 'AC' }]),
  connect((state) => ({
    first: get(state, 'firebase.data.AC')
  }),
  firebaseConnect((props) => {
    // Only attach listener if value from first exists
   const valueFromFirst = get(props, 'first.someValue')
    if (valueFromFirst) {
      return [{ path: `BD/${valueFromFirst}` }] // you can use 
    }
  }),
  connect((state, props) => ({
    second: get(state, `firebase.data.BD.${props.valueFromFirst}`)
  })
)

Will post here when there are any updates on this being worked on. Always open to PRs if anyone gets to it.

prescottprue avatar Aug 10 '18 00:08 prescottprue

Thanks a lot!

multimulti avatar Aug 10 '18 06:08 multimulti

Curious if there are any updates with this now?

0xdevalias avatar Nov 14 '20 11:11 0xdevalias