I implemented Firebase authentication using google sign-in (works perfectly). But I cannot navigate to my Home Component on successful sign-in. How can I achieve this?
I have implemented a check to see if I am logged in and then navigate to Home. It detects that I am logged in but it does not navigate to my Home Component.
const routes: Routes = [
{ path: '', pathMatch: 'full', redirectTo: 'login' },
{ path: 'login', component: LoginSignupComponent },
{ path: 'hc-home', component: HcHomeComponent, children: [
{ path: 'calender', component: CalenderComponent},
{ path: 'attendance', component: AttendanceComponent}
], canActivate: [CanActivateGuard]}
];
user$: Observable<User>;
constructor(private router: Router,
private afs: AngularFirestore,
private afAuth: AngularFireAuth) {
this.user$ = this.afAuth.authState.pipe(
switchMap(user => {
if (user) {
return this.afs.doc<User>(`users/${user.uid}`).valueChanges();
} else {
return of(null);
}
})
);
}
async googleSignIn() {
const provider = new auth.GoogleAuthProvider();
const credential = await this.afAuth.auth.signInWithPopup(provider);
return this.updateUserData(credential.user);
}
async signOut() {
await this.afAuth.auth.signOut();
return this.router.navigateByUrl('login');
}
private updateUserData(user) {
const userRef: AngularFirestoreDocument<User> = this.afs.doc(`users/${user.uid}`);
const data = {
displayName: user.displayName,
email: user.email,
photoURL: user.photoURL,
uid: user.uid
};
return userRef.set(data, { merge: true });
}
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
return this.auth.user$.pipe(
take(1),
map(user => !!user),
tap(loggedIn => {
console.log(loggedIn);
if (loggedIn === true) {
console.log('inside true function');
this.router.navigate(['/hc-home']);
}
if (!loggedIn) {
console.log('Access Denied');
this.router.navigateByUrl('login');
}
})
);
My expected results is to navigate to home upon successful logging in (which works perfectly) but for some reason it picks up that i am logged in and firebase authentication and my console confirms this but i keep staying on my login page. There are no error messages whatsoever.
In your auth guard you need to in your case return true
if user is allowed to navigate to the specified url. Currently you are trying to navigate to the url, but not actually telling angular to allow the user to navigate there. Also you don't need to try and navigate to home when user is allowed to navigate there. You have attached the guard on the route hc-home
, so angular already knows to route there if allowed. Change your code to:
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
return this.auth.user$.pipe(
take(1),
map(loggedIn => {
if (loggedIn) {
return true;
}
this.router.navigateByUrl('login');
return false;
}
})
);
Also, angularfire also has a plugin of its own authguard, where you don't actually need to write your own authguard: https://github.com/angular/angularfire2/blob/master/docs/auth/router-guards.md Just as another option thrown out there.