donc j'utilise une fenêtre contextuelle pour connecter mes utilisateurs avec Firebase:
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))),
)
}),
)
donc si je supprime window.location.href = 'visité' ceci tout fonctionne bien et il se met dans firebase. Je fais probablement quelque chose de stupide mais je ne comprends pas comment attendre que cette fonction déclenche setNewUserInformation et se termine avant de passer à la nouvelle page?
code de fonction:
export const setNewUserInformation = (userId) => {
return {
type: 'SET_NEW_USER_INFORMATION',
userId,
}
}
ceci a alors une épopée observable redux qui l'écoute:
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)
})
}
4 Réponses :
Utilisez-le comme ci-dessous
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)
})
}
Parce que sur puis vous pouvez retourner une promesse et résoudre plus tard. Nous pourrions réécrire le code ci-dessus comme ceci ci-dessous:
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)
})
}
Utilisez-vous React? Si oui, vous pouvez simplement utiliser didUpdate Cycle pour acheminer vers une nouvelle URL après l'envoi d'une action réussie. Déplacez votre "window.location.href = 'newRoute'" sous le contrôle ComponentDidUpdate avec accessoires.
J'utilise un composant fonctionnel. Je sais que je peux toujours le faire avec eux mais le problème est avec mon redux observable
Je pense, de toute façon
setNewUserInformation () est un créateur d'action, qui est sync. Vous n'avez pas besoin de l'attendre car cela ne renvoie rien d'utile à votre logique. Ce que vous devez faire, c'est déplacer window.location.href = 'newRoute' pour séparer la logique et la faire dépendre de l'état renvoyé par les créateurs d'action updatedUserInformationSuccess () et updatedUserInformationFailure (Erreur). Si votre composant est fonctionnel, mettez cette logique dans un useEffect . S'il s'agit d'un composant de classe, utilisez la méthode du cycle de vie ComponentDidUpdate .
ah cela m'a aidé. déplacé vers useEffect, puis en attente de mise à jour de redux avant de changer de page.cheers bro! marquez la question si cela ne vous dérange pas;)
à quoi ressemble la fonction?
@Ifaruki J'ajouterai du code. mais c'est juste un créateur d'action qui a alors un redux observable en l'écoutant
@Ifaruki a ajouté du code
le fait est que vous utilisez
awaitsur une fonction avec ne renvoie PAS de promesse.Je pensais que
fromrenvoie une promesse en redux-observableEh bien, vous utilisez
awaitsursetNewUserInformationqui renvoie un objet. wait n'attendra que cette fonctionah ouais, tu as raison. hmm, je me demande comment je peux résoudre ce problème