Auto login with firebase authentication

Discussão em 'Angular' iniciado por Kuba Goch, Abril 13, 2025.

  1. Kuba Goch

    Kuba Goch Guest

    I'm looking for a great solution for firebase authentication. I use angular with ngrx and firebase. I made authentication with these technologies but when I tried to implement auto login, it actually works but asynchronously so after refresh page I have to wait like 1s to receive my user. Is there any way to make it better with only client side? I can't even make no-auth guard for my auth routes because i get isAuthenticated: false at the beginning.

    auth.service.ts

    export class AuthService {
    fireAuth = inject(Auth);
    user$ = user(this.fireAuth);

    signUpByEmail(email: string, password: string, displayName: string): Observable<UserCredential> {
    return from(createUserWithEmailAndPassword(this.fireAuth, email, password)).pipe(
    switchMap((userCredential) => {
    return from(updateProfile(userCredential.user, { displayName })).pipe(
    map(() => userCredential)
    );
    })
    );
    }

    signInByEmail(email: string, password: string): Observable<UserCredential> {
    return from(signInWithEmailAndPassword(this.fireAuth, email, password));
    }

    signInByGoogle(): Observable<UserCredential> {
    const googleProvider = new GoogleAuthProvider();
    return from(signInWithPopup(this.fireAuth, googleProvider));
    }

    autoLogin(): Observable<User | null> {
    return this.user$.pipe(
    switchMap(userCredential => {
    if (!userCredential) return of(null);
    return this.formatUser(userCredential);
    }),
    catchError(() => of(null))
    );
    }

    logoutUser(): Observable<void> {
    return from(signOut(this.fireAuth));
    }

    formatUser(user: FireUser): Observable<User> {
    return from(user.getIdTokenResult()).pipe(
    map(({ token, expirationTime }) => new User(
    user.displayName,
    user.email,
    user.photoURL,
    token,
    user.uid,
    new Date(expirationTime)
    ))
    );
    }
    }


    auth.selector.ts

    export const AUTH_STATE_NAME = 'auth';

    const getAuthState = createFeatureSelector<AuthState>(AUTH_STATE_NAME);

    export const isAuthenticated = createSelector(getAuthState, (state) => {
    return state.user ? true : false;
    });

    export const getUser = createSelector(getAuthState, (state) => state.user);


    auth.effects.ts

    import { inject, Injectable } from '@angular/core';
    import { Router } from '@angular/router';
    import { Actions, createEffect, ofType } from '@ngrx/effects';
    import { exhaustMap, map, switchMap, tap } from 'rxjs/operators';
    import { AuthService } from '../auth.service';
    import { autoLoginFailed, autoLoginStart, autoLoginSuccess, logoutStart, logoutSuccess, signInGoogleStart, signInGoogleSuccess, signInStart, signInSuccess, signUpStart, signUpSuccess } from './auth.actions';

    @Injectable()
    export class AuthEffects {
    private actions$ = inject(Actions);
    private authService = inject(AuthService);

    signUp$ = createEffect(() => {
    return this.actions$.pipe(
    ofType(signUpStart),
    exhaustMap((action) => {
    return this.authService.signUpByEmail(action.email, action.password, action.displayName).pipe(
    switchMap((userCredentials) =>
    this.authService.formatUser(userCredentials.user).pipe(
    map((user) => {
    return signUpSuccess({
    user,
    redirect: true,
    })
    }
    )
    )
    )
    )
    })
    );
    });

    signIn$ = createEffect(() => {
    return this.actions$.pipe(
    ofType(signInStart),
    exhaustMap((action) => {
    return this.authService.signInByEmail(action.email, action.password).pipe(
    switchMap((userCredentials) =>
    this.authService.formatUser(userCredentials.user).pipe(
    map((user) => {
    return signInSuccess({
    user,
    redirect: true,
    })
    }
    )
    )
    )
    )
    })
    )
    });

    signInByGoogle$ = createEffect(() => {
    return this.actions$.pipe(
    ofType(signInGoogleStart),
    exhaustMap((action) => {
    return this.authService.signInByGoogle().pipe(
    switchMap((userCredentials) =>
    this.authService.formatUser(userCredentials.user).pipe(
    map((user) => {
    return signInGoogleSuccess({
    user,
    redirect: true,
    })
    }
    )
    )
    )
    )
    })
    )
    });

    logoutUser$ = createEffect(() => {
    return this.actions$.pipe(
    ofType(logoutStart),
    switchMap(() => {
    return this.authService.logoutUser().pipe(
    map(() => logoutSuccess())
    );
    })
    );
    });

    autoLogin$ = createEffect(() => {
    return this.actions$.pipe(
    ofType(autoLoginStart),
    switchMap(() => {
    return this.authService.autoLogin().pipe(
    map(user => {
    return user ? autoLoginSuccess({ user }) : autoLoginFailed();
    }),
    );
    })
    )
    });

    redirectAfterAuth$ = createEffect(() => {
    const router = inject(Router);

    return this.actions$.pipe(
    ofType(signInSuccess, signUpSuccess, signInGoogleSuccess),
    tap((action) => {
    if (action.redirect) {
    router.navigate(['/dashboard']);
    }
    })
    );
    },
    { dispatch: false }
    );
    }```

    Continue reading...

Compartilhe esta Página