问题
async login({ commit }, { email, password }) {
let result
try {
result = await firebase.auth().signInWithEmailAndPassword(email, password)
commit('setUser', result.user)
} catch (err) {
commit('setError', err)
}
}
This is an action in Vuex. When this runs, I expect the commit('seteError', err)
to be a valid error handler for the error returned from catch (err)
. Instead, I get an 'Uncaught' exception and execution stops.
Would appreciate any insights from anyone who managed to use async
with firebase.auth()
回答1:
I ran into the same issue today - it appears to be due to the implementation of the Closure promise library that firebase auth uses. There is a closed issue in the firebase-js-sdk project here with some details on it. Ultimately, what is happening with this implantation is a timeout is getting set that throws an exception outside of the scope of the try/catch
:
To avoid this, the exception needs to be handled by calling .catch()
on the returned promise e.g.:
firebase.auth().signInWithEmailAndPassword(email, password)
.catch((ex) => { /* handle exception */ });
As I have all of my firebase logic wrapped and centralized, what I ended up doing is wrapping the firebase Promise in one of my own:
export async function signIn(email, password) {
return new Promise((resolve, reject) => {
firebase.auth().signInWithEmailAndPassword(email, password)
.then((userCreds) => resolve(userCreds))
.catch((reason) => reject(reason));
});
}
The wrapper function can then be called using async await:
try {
const result = await signIn(email, password)
// Do what you need to with the result
} catch (ex) {
// Handle any exceptions
}
回答2:
This is how I managed to handle firebase authentication with async in Vuex. I needed to use onAuthStateChanged
async login({ commit, dispatch }, { email, password }) {
try {
await firebase.auth().signInWithEmailAndPassword(email, password)
await dispatch('session')
} catch (err) {
commit('setError', err)
}
}
Where the 'session' dispatch simply does:
async session({ commit }) {
let user
try {
user = await userInSession()
commit('setUser', user)
} catch (err) {
console.error(err)
commit('setUser', {})
}
}
and the userInSession function uses onAuthStateChanged
:
const userInSession = function () {
return new Promise((resolve, reject) => {
firebase.auth().onAuthStateChanged((user) => {
if (user) {
resolve(user.uid)
} else {
reject(Error('No user authenticated'))
}
})
})
}
来源:https://stackoverflow.com/questions/51819349/getting-uncaught-after-catching-error-in-firebase-auth-with-async