I am using:
[email protected]
[email protected]
[email protected]
I am working with Firebase and I use a pinia Store for the authentication. The way I am doing it as of now is:
- I have a pinia store called storeAuth.ts with following code (part of the code):
...
export const useStoreAuth = defineStore('storeAuth', () => {
const user = ref(null)
const loading = ref(false)
const errorMessage = ref("")
const successMessage = ref("")
const router = useRouter()
const init = () => {
onAuthStateChanged(auth, (firebaseUser) => {
if (firebaseUser) {
user.value = {}
user.value.id = firebaseUser.uid
user.value.email = firebaseUser.email
console.log('logged in:',user);
} else {
user.value = null
//console.log('logged out');
}
});
}
...
const loginUser = (credentials) => {
successMessage.value = ""
errorMessage.value = ""
loading.value = true
signInWithEmailAndPassword(auth, credentials.email, credentials.password).then((userCredential) => {
loading.value = false
const firebaseUser = userCredential.user;
router.push('/')
}).catch((error) => {
loading.value = false
//console.log('Error while logging in:',error.message);
switch (error.code) {
case 'auth/user-not-found':
errorMessage.value = "Email and/or password incorrect"
break;
case 'auth/wrong-password':
errorMessage.value = "Email and/or password incorrect"
break;
case 'auth/too-many-requests':
errorMessage.value = "Too many requests. Please reset your password"
break;
default:
errorMessage.value = "There was an error during login"
break;
}
});
}
...
So I call the function loginUser with my credentials and then I am logged in.
Now I would like to use route guards in order to prevent going to the login page when user is signed in. I tried to do it getting the user from the pinia store as I am storing the value in a user variable in my pinia store in the init function. But it is always null when entering in the router/index.ts . So I have tried the following approach :
I enter this following config in my router file :
let currentUser = null
const getCurrentUser = async () => {
return new Promise<void>((resolve) => {
onAuthStateChanged(auth, (user) => {
currentUser = user
resolve()
})
})
}
const setupNavigationGuards = async () => {
await getCurrentUser()
router.beforeEach((to, from, next) => {
currentUser = auth.currentUser
if (currentUser && (to.name === 'signin' || to.name === 'register')) {
next({ name: 'home' })
} else {
next()
}
})
}
// Call the setupNavigationGuards function
setupNavigationGuards()
But it is not working and on top of that I would prefer to use the user from my pinia and not the user from Firebase because I would like also to add some roles and show menus to the admins only…
2
Answers
I found a way to refactor my init function into a Promise: In my storeAuth, the init function looks like this:
and in my router index file, I call it like this:
To get the correct user value from your store you have to call your store’s
useStoreAuth
function from inside the route guard.