简体   繁体   中英

How to get AngularFire2 authentication as an observable?

I want to after authenticated set isAuthenticated:boolean to True after successful Federated Google Sign-in, or user is signed in state.

import {Injectable} from '@angular/core';
import {AngularFire} from 'angularfire2';
import {Observable} from 'rxjs/Observable';


//this current code is not making sense. Any suggestion 
//to make it an Observable for Signin and Logout?
@Injectable()
export class AuthService {
  isAuthenticated:boolean = false;
  authObj: Observable<any>;

  constructor(public af:AngularFire) {
    this.authObj = af.auth;
  }

  signin() {
    //I want to make AngularFire2 Authentication token/obj an Observable. So this will keep emitting an Observable
    //that return True.... after successful Federated Google Signin. I want my other component to subscribe to this Observable.
    return this.authObj.do(val => this.af.auth.login());
    this.isAuthenticated = true;
  }

}

I wrote a piece that takes the bits and pieces and joins them together. You might have to create an Auth Service like this:

import 'rxjs/add/operator/map';
import 'rxjs/add/operator/first';
import { Observable } from 'rxjs/Observable';

import { Injectable } from '@angular/core';
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { AngularFire } from 'angularfire2';

@Injectable()
export class AuthGuard implements CanActivate{
  public allowed: boolean;

  constructor(private af: AngularFire, private router: Router) { }

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

Check the AngularFire2 Authentication article for more info.

Just subscribe to the auth object to get notified when there is a user object or not...

  var auth = this.af.auth.subscribe( (user) => {
    debugger;
    if (user) {
      // User signed in!
      var uid = user.uid;
      console.log(uid)
    } else {
      // User logged out
      console.log("no user")
    }
  });

With Angular v6 , Firebase v5.0.* and angularfire2 5 rc 10 you can do something like this.

...
import { AngularFireAuth } from 'angularfire2/auth';
import { map } from 'rxjs/operators';

...
export class DashboardGuard implements CanActivate, CanActivateChild {

  constructor(private router: Router, private auth: AngularFireAuth) { }
  // #2
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    // #1
    return this.auth.authState.pipe(
      // #3
      map((user: any) => user !== null) // <--- [1]
    );

  }

  canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return this.canActivate(route, state);
  }

}

Directly with AngularFireAuth 's authState just pipe it down and check if user is not equal to null [1] .

  1. authState returns Observable<firebase.User>
  2. canActivate() returns Observable<boolean> | Promise<boolean> | boolean Observable<boolean> | Promise<boolean> | boolean
  3. subscribing to authState will emit null if not authenticated else emits firebase.User (see screenshot below).

I've just discovered that I can now do this with the latest versions -> return an Observable<boolean> in canActivate ... Because in the last versions although in the documentation it says that canActivate returns Observable<boolean> it gives me tons of errors. but now yea!

btw I just want to share how I write route guards before angular v6. using promises

constructor(private router: Router, private afAuth: AngularFireAuth) {}

canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
  const promise = new Promise(
    (resolve, reject) => {
      this.afAuth.authState.subscribe((state: any) => {
        resolve(state !== null);
      });
    }
  );

  return promise.then((data: boolean) => {
    if (data) {
      return data;
    } else {
      this.router.navigate(['/']);
    }
  });
}

在此输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM