0

I want my app to route to home : "" when the user logs in with their google email. Everything works except the canActivate routeGuard. this.authService.isLoggedIn returns false after I try to navigate to "" during the AuthLogin function. After logging in, the routeguard routes to "login" and not "", if I try to go to "" straight after, it works because this.authService.isLoggedIn shows true in the console.log. So it seems the canActivate needs a way to wait until this.authService.isLoggedIn updates, any ideas?

app-routing.module:

import { AuthGuard } from "./shared/guard/auth.guard";

const routes: Routes = [
  { path: "", component: HomeComponent, canActivate: [AuthGuard] },
  { path: "login", component: LoginComponent },
  { path: "results", component: ResultsComponent },
  { path: "profile", component: ProfileComponent },
  // otherwise redirect to home
  { path: "**", redirectTo: "" },
];

auth.service:

// Returns true when user is looged in and email is verified
  get isLoggedIn(): boolean {
    const user = JSON.parse(localStorage.getItem("user"));
    return user !== null && user.emailVerified !== false ? true : false;
  }

  googleLogin() {
    return this.AuthLogin(new firebase.auth.GoogleAuthProvider());
  }

  async AuthLogin(provider: firebase.auth.AuthProvider) {
    try {
      const result = await this.afAuth.auth.signInWithPopup(provider);
      this.SetUserData(result.user);
      this.router.navigate([""]);
    } catch (error) {
      window.alert(error);
    }
  }

  SetUserData(user) {
    const userRef: AngularFirestoreDocument<any> = this.afs.doc(`users/${user.uid}`);
    const userData: User = {
      uid: user.uid,
      email: user.email,
      displayName: user.displayName,
      photoURL: user.photoURL,
      emailVerified: user.emailVerified,
    };
    return userRef.set(userData, {
      merge: true,
    });
  }

auth.guard:

import { AuthService } from "src/app/services/auth/auth.service";

@Injectable({
  providedIn: "root",
})
export class AuthGuard implements CanActivate {
  constructor(public authService: AuthService, public router: Router) {}
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    console.log(this.authService.isLoggedIn);
    if (this.authService.isLoggedIn !== true) {
      this.router.navigate(["login"]);
    }
    return true;
  }
}
artworkjpm
  • 1,255
  • 2
  • 19
  • 40
  • Your AuthGuard is checking for the isLoggedIn function from your Auth Service in which it needs the localStorage USER. Now the problem is, based on the code you posted, I don't see on your google login function where you are setting the localStorage user. – dom.macs Sep 03 '21 at 03:44

1 Answers1

0

You need to setup a Promise for SetUserData since userRef relies on a Firestore request. After the promise resolves, then navigate to "".

Joshua McCarthy
  • 1,739
  • 1
  • 9
  • 6