When I refresh the page (F5) and the app restarts, the AuthActions.login action is dispatched to set the user property in the (ngrx) store.
stateChanged = onAuthStateChanged(getAuth(), (user) => {
if (user) { this.store.dispatch(AuthActions.login({ user })); }
else { console.log('USER-LOGGED-OUT'); }
});
The issue is that for a moment, the app shows the ‘welcome’ page while still fetching the ‘user’ object from the server, and only after that does it navigate to the ‘books’ page.
Is there a way to wait for the ngrx to set the user object before navigating to a path?
‘app.routes.ts’
export const APP_ROUTES: Routes = [
{
path: '',
component: ShellComponent,
children: [
{
path: '', pathMatch: 'full', redirectTo: 'welcome' },
{
path: 'welcome',
loadChildren: async () => (await import('@welcome/feat/welcome')).WELCOME_ROUTES,
},
{
path: '',
canMatch: [() => inject(Store).select(selectUser).pipe(map((user) => user!!))],
providers: [provideState(booksFeature),provideEffects(booksEffects)],
children: [
{
path: 'books',
loadChildren: async () => (await import('@books/feat/books')).BOOKS_ROUTES,
},
],
},
{
path: '**',
redirectTo: 'welcome',
},
],
},
];
2
Answers
What I’d probably do in your case is to provide an
APP_INITIALIZER
function that waits for the server to responds before launching the application.You can do by providing the
APP_INITIALIZER
token in the application boostraping and passing the initializer function in theuseFactory
property :Angular will now wait for the
getAuthUser
function to resolve before loading the application, you can run additional logic in it to ensure that your AuthStore is correctly populated.That’s the expected behavior of the code you shared.
Firebase automatically restores the user’s authentication state when it loads the page. But doing that requires it to call to the server, e.g. to check whether the account has been disabled. While this call is going on, the current user will still be null – and you render that differently.
The way to solve this, is to store some indication whether you expect a logged in user in the local state that you can check synchronously when the page loads. So:
onAuthStateChanged
then shows that the local state was wrong after all, correct the UIYou may still have a flash in this case, but the chances are much smaller. Firebaser Michael Bleigh explained this technique at Google I/O a few years back, so check that out here: https://www.youtube.com/watch?v=NwY6jkohseg&t=1311s