简体   繁体   中英

Firebase: How To update the value of a record Asynchronously in React Native?

I was searching for a solution to update a part of a record in firebase database and eventually I found out that I need the uid of the record. So I first have a query to retrieve the uid and then I perform my update. The problem is that the second console log is executed first since the first query is asynchronous and therefore the value of the uid at the first run is null. How can I edit my code in order to first get the uid and then perform the Update operation based on the result of the first query ? Here is my code :

export const cupChanged = ({cup}) => {
  const {currentUser} = firebase.auth();
  let userSettingsUid = null;
  firebase
    .database()
    .ref(`/users/${currentUser.uid}/settings`)
    .on('value', snapshot => {
      if (snapshot.val() != null) {
        const userSettings = _.map(snapshot.val(), (val, uid) => {
          return {...val, uid};
        });
        userSettingsUid = userSettings[0].uid;
        console.log('First stage is : ' + userSettingsUid);
      }
    });
  return dispatch => {
    console.log('Second stage is : ' + userSettingsUid);
    firebase
      .database()
      .ref(`/users/${currentUser.uid}/settings/${userSettingsUid}`)
      .update({
        cup,
      })
      .then(() => {
        dispatch({
          type: CUP_CHANGED,
          payload: cup,
        });
      });
  };
};

By using the once() method which "listens for exactly one event of the specified event type" and returns a Promise which resolves with a DataSnapshot , you will be able to chain the different Promises, as follows:

  export const cupChanged = ({ cup }) => {
    const { currentUser } = firebase.auth();
    let userSettingsUid = null;

    return firebase
      .database()
      .ref(`/users/${currentUser.uid}/settings`)
      .once('value')
      .then(snapshot => {
        if (snapshot.val() != null) {
          const userSettings = _.map(snapshot.val(), (val, uid) => {
            return { ...val, uid };
          });
          userSettingsUid = userSettings[0].uid;
          console.log('First stage is : ' + userSettingsUid);
          return firebase
            .database()
            .ref(`/users/${currentUser.uid}/settings/${userSettingsUid}`)
            .update({
              cup
            });
        } else {
          throw new Error('Snapshot is null');
        }
      })
      .then(() => {
        dispatch({
          type: CUP_CHANGED,
          payload: cup
        });
      })
      .catch(err => {
        //....
        //return .... 
      });
  };

You could try below

export const cupChanged = ({cup}) => {
    return async dispatch => {
        const {currentUser} = firebase.auth();
        let userSettingsUid = null;
        const snapshot = await firebase
            .database()
            .ref(`/users/${currentUser.uid}/settings`)
            .once('value');
        if (snapshot.val() != null) {
            const userSettings = _.map(snapshot.val(), (val, uid) => {
              return {...val, uid};
            });
            userSettingsUid = userSettings[0].uid;
            console.log('First stage is : ' + userSettingsUid);
            await firebase  
                  .database()
                  .ref(`/users/${currentUser.uid}/settings/${userSettingsUid}`)
                  .update({
                    cup,
                  });
            dispatch({
              type: CUP_CHANGED,
              payload: cup,
            });
        }
    }   
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM