Vue Pinia Firebase Authentication Fetch currentUser before Route Guard
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In a Vue app that uses Firebase Authentication, currentUser is not reliably available the moment the page reloads. Firebase restores the session asynchronously, so a route guard that checks too early can redirect an authenticated user to the login page before the auth state has finished initializing.
Wait for Firebase Auth Exactly Once
The clean pattern is to let your Pinia auth store own the initialization promise. The store waits for the first onAuthStateChanged callback, saves the user, and marks itself ready so the rest of the app can await that single piece of state.
This avoids the common mistake of subscribing in every guard call. You only wait for the initial auth restoration once, then read store state after that.
Await the Store Before the Route Check
With the store in place, the router guard becomes predictable. It waits for auth readiness and only then decides whether the route should continue.
This pattern removes flicker because the decision happens after Firebase has restored the previous session, not before.
Keep Long-Lived Auth State Separate From Startup Readiness
The first auth callback solves the startup problem, but your app may still need a persistent listener if the user can sign out, sign in on another tab, or refresh tokens while the app is open. A common pattern is to use one method for the one-time startup wait and another for a long-lived subscription that keeps the store synchronized.
That separation keeps the guard logic simple. The guard only cares about readiness and current user state, while the store remains responsible for ongoing auth events.
Avoid Reading currentUser Directly in the Guard
getAuth().currentUser can be null during initialization even when a valid session exists. Reading it directly in the guard often works on a warm app state and then fails on a hard refresh, which makes the bug seem random.
Treat the store as the source of truth after initialization. That gives you one consistent place to handle loading, user state, and any fallback redirect logic.
Common Pitfalls
- Checking
getAuth().currentUserbefore Firebase has finished restoring the session from storage. - Registering a new
onAuthStateChangedlistener on every route navigation and never cleaning it up. - Running the guard before Pinia is installed on the app instance, which makes the store unavailable in router code.
- Redirecting every unauthenticated request to login without excluding the login route itself, which can create a redirect loop.
- Mixing startup readiness and long-lived auth synchronization into one unclear method, which makes later maintenance harder.
Summary
- Firebase auth restoration is asynchronous, so guards must wait for readiness.
- Put the one-time initialization promise in the Pinia store.
- Await that store method inside
beforeEachbefore checking protected routes. - Use store state rather than reading
currentUserdirectly during startup. - Separate initial auth loading from long-lived auth subscriptions for clearer code.

