mcnamee / react-native-starter-kit

:rocket: A React Native boilerplate app to get you up and running very, very quickly :rocket:
MIT License
3.35k stars 865 forks source link

Possible race condition sometimes gives error: Cannot read property 'uid' of null #199

Closed GitHubGreg closed 6 years ago

GitHubGreg commented 6 years ago

First off, I love this starter kit. Thank you so much for the valuable contribution.

I have been building an app with for a few weeks and very rarely, perhaps once every two days, navigating to a screen will return an error:

Cannot read property 'uid' of null

Looking at getFavourites for example:

export function getFavourites(dispatch) {
  if (Firebase === null) return () => new Promise(resolve => resolve());

  const UID = Firebase.auth().currentUser.uid;
  if (!UID) return false;

  const ref = FirebaseRef.child(`favourites/${UID}`);

  return ref.on('value', (snapshot) => {
    const favs = snapshot.val() || [];

    return dispatch({
      type: 'FAVOURITES_REPLACE',
      data: favs,
    });
  });
}

Is it possible this creates a race condition and there are times where the component loads but Firebase did not have the time to provide currentUser (and so getFavourites has replaced uid in the store with null)?

I can't reproduce the error on command, it just happens occasionally and crashes the app.

This forum thread seems to explain it clearly and give a remedy. But before I try implementing it, I wanted to be sure I am understanding correctly and see if you think this would be a viable solution.

Thanks very much.

GitHubGreg commented 6 years ago

I found a way to reproduce this and a solution in case it helps anyone. The problem arose anytime I loaded a screen immediately after the app loaded. There was not enough time for the firebase call to finish. I therefore start componentDidMount with the call to get the member data, and only then do I load the data which requires the uid:

this.props.fetchMemberData().then(() => this.fetchParticipantsOnMount());