I'm currently using React JS with Firebase to handle signIn operations.
Me and the team decided to use the Custom Auth System way for sign in. So from the Back End side we generate a custom token then the Front End executes the sign in via signInWithCustomToken.
Everything works like a charm until here, but once I'm signed in, if I refresh the page the currentUser object becomes null so I don't have the possibility to invoke on it the method getIdToken(true) to refresh the token. The firebase.auth().currentUser.getIdToken(true) method is called every time I make an http request with axios (using an interceptor for adding the Authorization field to the request). If I sign in and make the http request without reloading, it works fine, but if I refresh I get an error because the currentUser object loses its content and becomes null.
I've spent more or less 8 hours surfing on the Internet searching for a solution. I've already seen people saying that the solution is to take the user inside the onAuthStateChanged observer, but the problem is that i cannot enter the observer to take the value of the user when I make an http request because the observer it's not a function that I can call when I need.
Also I've tried to save the user object returned by onAuthStateChanged observer when it triggers (during the sign in or sign out), on localStorage, but the user object it's different from the one returned and it doesn't have inside the proto the getIdToken function. So it's useless for me.
I've also tried to use the firebase.auth().setPersistence(firebase.auth.Auth.Persistence.SESSION), passing to it the user object returned by the onAuthStateChanged observer, but nothing changed.
This is a my project's code:
****** AXIOS REQUEST INTERCEPTOR ******
instanceAXIOS.interceptors.request.use(
async config => {
const { refreshedToken } = await refreshUserTokenTEST()
config.headers.Authorization = `Bearer ${ refreshedToken }`
return config
},
error => Promise.reject(error)
)
****** REFRESH TOKEN ******
const refreshUserTokenTEST = () => {
try {
return firebase
.auth()
.currentUser
.getIdToken(true)
.then(token => {
return { status: 200, refreshedToken: token }
})
.catch(err => {
console.error(err)
return { status: 500, refreshedToken: null }
})
} catch (exc) {
console.error("ERROR DURING TOKEN REFRESH")
return { status: 404, refreshedToken: null }
}
}
****** firebasePersistenceOption function ******
const firebasePersistenceOption = async (userObject) => {
return firebase
.auth()
.setPersistence(firebase.auth.Auth.Persistence.SESSION)
.then(function() {
return userObject
})
.catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
})
}
****** onAuthStateChanged OBSERVER ******
firebase.auth().onAuthStateChanged(async function(user) {
if (user) {
console.log("LOGGED IN")
await firebasePersistenceOption(user)
} else {
console.log("LOGGED OUT")
}
})
Like I said, without reloading the page, everything works fine, so there are no errors in the code (I almost wish it was that).