Hi all I am working on a sharing app with angular and firebase and I have encountered a problem that I have 1. Never encountered before 2. Tried solutions from stack overflow to no avail. I am implementing an auth guard into my app so that certain pages can only be viewed by authenticated users. Here is my sign in directive code:
import { Directive, HostListener } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
import * as firebase from 'firebase/app';
@Directive({
selector: '[appGoogleSignin]',
})
export class GoogleSigninDirective {
constructor(private afAuth: AngularFireAuth) {}
@HostListener('click')
onclick() {
this.afAuth
.setPersistence(firebase.default.auth.Auth.Persistence.LOCAL)
.then(() => {
this.afAuth.signInWithPopup(
new firebase.default.auth.GoogleAuthProvider()
);
});
}
}
Here is my authguard code:
import { Injectable } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
import {
CanActivate,
ActivatedRouteSnapshot,
RouterStateSnapshot,
UrlTree,
} from '@angular/router';
import { Observable } from 'rxjs';
import { SnackService } from '../services/snack.service';
@Injectable({
providedIn: 'root',
})
export class AuthGuard implements CanActivate {
constructor(private afAuth: AngularFireAuth, private snack: SnackService) {}
async canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Promise<boolean> {
const user = await this.afAuth.currentUser;
const isLoggedIn = !!user;
if (!isLoggedIn) {
this.snack.authError();
}
return isLoggedIn;
}
}
And here is my implementation of the auth guard:
path: 'upload',
loadChildren: () =>
import('./upload/upload.module').then((m) => m.UploadModule),
canActivate: [AuthGuard],
},
I have tried multiple solutions on stack overflow including setting the persistence state to both session and local. None have worked for me.
The this.afAuth.currentUser
value is refreshed asynchronously when you load the page. So by the time your code accesses this.afAuth.currentUser
it probably hasn't been set yet.
Instead of accessing the this.afAuth.currentUser
value synchronously, observe the auth.user
stream to make sure you are always reacting to the latest authentication state. See also the first code sample in Getting started with Firebase Authentication.