KhoPhi
KhoPhi

Reputation: 9537

Using canActivate Angular with AngularFirebase2

I've read and tried a trillion suggestions already.

Some 2 years ago, I did Auth Guard in Angular using AngularFire2 like this:

 canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    this.af.auth.subscribe((auth) =>  {
      if(auth == null) {
        this.router.navigate(['/login']);
        this.allowed = false;
      } else {
        this.allowed = true;
      }
    })
    return this.allowed;
  }

Today, I'm trying to replicate same auth guard, using today's javascript

Angular CLI: 7.3.2
Node: 11.10.0
OS: linux x64
Angular: 7.2.5
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router, service-worker

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.13.2
@angular-devkit/build-angular     0.13.2
@angular-devkit/build-optimizer   0.13.2
@angular-devkit/build-webpack     0.13.2
@angular-devkit/core              7.3.2
@angular-devkit/schematics        7.3.2
@angular/cli                      7.3.2
@angular/fire                     5.1.1
@angular/pwa                      0.12.4
@ngtools/webpack                  7.3.2
@schematics/angular               7.3.2
@schematics/update                0.13.2
rxjs                              6.3.3
typescript                        3.2.4
webpack                           4.29.0

I understand a few things have changed with rxjs, so something like this

this.af.auth.subscribe((auth) => {

now becomes

this.af.authState.pipe(map(auth) => {

Except doing the above causes the browser tab to hang on me.

I've seen at least 15 different questions on how to do route guarding using AngularFirebase, and they all take a different approach.

I know things will change (very likely) in the coming months how to do this, but as at 2019, Feb 18, how do you do route guarding using AngularFire2?

Edit

Here's where it gets interesting/weird. I tried @sergey-mell answer below.

Here's how I'm applying the authGuard within the routes

const routes: Routes = [
  { path: 'auth', loadChildren: './auth/auth.module#AuthModule' },
  {
    path: '',
    component: MenuComponent,
    children: [
      { path: '', component: HomeComponent },
      { path: 'new', component: NewcustomerComponent },
      { path: ':customer_id', component: CustomerdetailComponent }
    ],
    canActivate: [AuthGuard]
  }
];

What happens is, if not logged in, and I visit directly in the browser, localhost:4200/, the browser hangs.

In console, Chrome informs me to visit the URL below

https://crbug.com/882238

I follow the link, and I'm told I don't have permission to view the bug. The bug that is bugging me. Okay.

enter image description here

So is there something I'm missing?

Upvotes: 0

Views: 138

Answers (1)

Sergey Mell
Sergey Mell

Reputation: 8050

Preface:

  1. If to look through the Angular docs Guard can return an Observable which resolves into boolean.
  2. AngularFire docs show that we can use AngularFireAuth.user observable to check user auth state.

So, as to me, your guard should look as follows:

@Injectable()
class LetMeInGuard implements CanActivate {
  constructor(private afAuth: AngularFireAuth,
              private routes: Router) {}

  canActivate(route: ActivatedRouteSnapshot, 
              state: RouterStateSnapshot): Observable<boolean> {
    return this.afAuth.user.pipe(
      map(user => {
         if (!user) {
             this.router.navigate(['/login']);
         }
         return !!user;
      })
    );
  }
}

Upvotes: 1

Related Questions