Reputation: 7642
so I'm using a popup to log my users in with firebase:
const loginToApp = (provider) => {
firebaseApp
.auth()
.signInWithPopup(provider)
.then(async (result) => {
if (result.additionalUserInfo.isNewUser) {
// problem is this line
await setNewUserInformation(result.user.uid)
}
const { user } = result
setUser(user)
// and this line
window.location.href = 'newRoute'
})
.catch((error) => {
console.log('ERROR:', error)
})
}
so if I remove window.location.href = 'visited'
this all works fine and it sets in firebase. I'm probably doing something stupid but I cant figure out how to wait for this function to fire setNewUserInformation
and to complete before I move to the new page?
function code:
export const setNewUserInformation = (userId) => {
return {
type: 'SET_NEW_USER_INFORMATION',
userId,
}
}
this then has a redux observable epic listening to it:
return action$.pipe(
ofType('SET_NEW_USER_INFORMATION'),
mergeMap((action) => {
return from(
firebaseApp.database().ref(firebaseRef).update(userInformation),
).pipe(
mergeMap(() => {
return [updatedUserInformationSuccess()]
}),
catchError((error) => of(updatedUserInformationFailure(error))),
)
}),
)
Upvotes: 2
Views: 1129
Reputation: 1483
setNewUserInformation()
is an action creator, which is sync. You do not need to wait for it as it does not return anything useful to you logic. What you need to do, is move window.location.href = 'newRoute'
to separate logic, and make it depend on state returned from action creators updatedUserInformationSuccess()
and updatedUserInformationFailure(error). If your component is functional, put this logic in a useEffect
. If it is a class component, use ComponentDidUpdate
lifecycle method.
Upvotes: 1
Reputation: 66
Are you using React? If yes, then you can simply use didUpdate Cycle to route to new url after successful action dispatched. Move your "window.location.href = 'newRoute'" under the ComponentDidUpdate with props check.
Upvotes: 0
Reputation: 147
Because on then
You can returned a Promise and resolve later. We could re-write the code above like this below:
const loginToApp = (provider) => {
firebaseApp
.auth()
.signInWithPopup(provider)
.then((result) => {
if (result.additionalUserInfo.isNewUser) {
// return for next resolve function
return setNewUserInformation(result.user.uid).then(() => result);
}
return result;
})
.then((result) => {
// after all above promises resolve
const { user } = result
setUser(user)
// and this line
window.location.href = 'newRoute'
})
.catch((error) => {
console.log('ERROR:', error)
})
}
Upvotes: 0
Reputation: 954
Use it like below
const loginToApp = (provider) => {
firebaseApp
.auth()
.signInWithPopup(provider)
.then(async (result) => {
new Promise((resolve, reject) => {
if (result.additionalUserInfo.isNewUser) {
// problem is this line
setNewUserInformation(result.user.uid)
}
const { user } = result
resolve(user)
}).then((user)=>{
setUser(user)
// and this line
window.location.href = 'newRoute'
})
})
.catch((error) => {
console.log('ERROR:', error)
})
}
Upvotes: 0