0
votes

I try to check if current user exists (logged in) or not and returning it in the auth guard.

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    firebase.auth().onAuthStateChanged((user: firebase.User) => {
      if (user) {
        return true;
      }
      return false;
    });
  }

But I got this error:

A function whose declared type is neither 'void' nor 'any' must return a value.

Looks like the return statements are not linked to the canActivate function.

2
You need to add return before firebase (and change the function signature to return Observable<boolean>). - John Montgomery
thats the solution but not the why. - mnlfischer

2 Answers

1
votes

As your guard canActivate methods return type is boolean and you are not return any thing you are getting the error.

You can return a boolean to resolve this issue. But in your case I can see is your return type will be observable and inside the observable you want to return true or false.

So you change you guard t.

you need to do 2 thing as below

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): : boolean | Observable<boolean> | Promise<boolean> {
     return firebase.auth().onAuthStateChanged((user: firebase.User) => {
      if (user) {
        return true;
      }
      return false;
    });
  }

You need to check what is the return type of firebase.auth().onAuthStateChanged() normally these kind of methods returns observable. If that is the case then you need to change it to as below

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): : boolean | Observable<boolean> | Promise<boolean> {
     return firebase.auth().onAuthStateChanged().map((user: firebase.User) => {
      if (user) {
        return true;
      }
      return false;
    });
  }
1
votes

canActivate method should return Observable<boolean> | Promise<boolean> | boolean you should create a promise or observable from onAuthStateChanged callback:

 canActivate(next: ActivatedRouteSnapshot,
              state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    return new Promise((resolve, reject) => {
      firebase.auth().onAuthStateChanged((user: firebase.User) => {
        if (user) {
          resolve(true);
        } else {
          this.router.navigate([ '/login' ], { queryParams: { returnUrl: state.url } });
          resolve(false);
        }
      });
    });
  }