Reputation: 175
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,
});
});
};
};
Upvotes: 0
Views: 610
Reputation: 4162
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,
});
}
}
};
Upvotes: 1
Reputation: 83093
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 ....
});
};
Upvotes: 2