0

I am creating an application in Ionic that uses Firebase to authenticate users. As soon as an authentication is performed successfully, save its data in the Firestore. One of the items in the collection on the user's Firestore is the 'activeUser: Boolean' where I can monitor by means of an observable (user$) return by the 'AngularFirestore' plugin after login.

I created a Guard file of type canActivate in order to monitor a 'activeUser' flag from Firestore as soon as it changes to 'False' and the user tries to navigate to another page it will be 'logged out' and informed that its user has been deactivated by the administrator .

I am new to Ionic and some subjects like Guards and Observables I have doubts. I would like you to help me if the code below is plausible or there are points that we can improve.

Another question concerns the Observables. Can I subscribe for observable USER$ whenever I need it in the app? Should I take any care with performance? Where do I unsubscribe on the ionic?

If anyone has code examples using Guard and Firestore or some tutorial link I would be grateful.

Thanks to all for your help

authentication.Service.ts

/**
 * Funcao que fica 'ouvindo' o estado da autenticado
 * e obtem os dados armazenados no firestore referente
 * ao usuario logado.
 **/
this.user$ = this.afAuth.authState.pipe(
  switchMap(user => {
    if (user) {
      return this.afStore.doc<IUser>(`users/${user.uid}`).valueChanges();
    } else {
      return of(null);
    }
  })
);

user-active.guard.ts

export class UserDisabledGuard implements CanActivate {

  constructor(private authService: AuthenticationService, private router: Router) { }

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> {

    return this.authService.user$.pipe(
      filter(val => val !== null),
      take(1), 
      map(response => {
        if (response.activeUser) {
          this.authService.logout();
          Storage.remove({ key: TOKEN_KEY });
          this.authService.isAuthenticated.next(false);
          this.router.navigateByUrl('/login');
          return false;
        } else {
          return true;
        }
      })
    );
  }
}

1 Answers1

0

I use Angular, but I think it's similar. The way you did in both service and guard is OK. But I won't do so many operations in your guard pipe function. Cause some of them look like nothing to do with the original observable object.

Firebase authentication provides authstate method for us to check the state. What I did is to check the id of user is undefined or not

this.afAuth.authState.pipe(
      map((data) => {
        return data?.uid
      })
    ) 

afAuth : AngularFireAuth

And in guard.ts , I return an Observable<boolean | UrlTree> object. So that the route guard could check and redirect. This is what I did, https://medium.com/p/angular-route-setting-login-and-route-guard-canactivate-fab53eb1715a

broti
  • 1,338
  • 8
  • 29
A-Hsien
  • 13
  • 4