google - Angular 2 AuthGuard+Firebase Auth
firebase login angular 2 (2)
Complete el observable usando .take (1) para hacer que el componente se renderice.
import {Observable} from "rxjs/Observable";
import ''rxjs/add/operator/map'';
import ''rxjs/add/operator/take'';
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return this.af.auth.map((auth) => {
if (!auth) {
this.router.navigateByUrl(''login'');
return false;
}
return true;
}).take(1);
}
Estoy tratando de construir una ruta AuthGuard para Angular 2 usando Firebase Auth.
Este es el servicio AuthGuard:
import { Injectable } from ''@angular/core'';
import { CanActivate, Router,
ActivatedRouteSnapshot,
RouterStateSnapshot } from ''@angular/router'';
import { AuthService } from ''./auth.service'';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private AuthService: AuthService,
private router: Router) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
if (this.AuthService.loggedIn) { return true; }
this.router.navigate([''login'']);
return false;
}
}
Y este es el AuthService que verifica si el usuario inició sesión y vincula el resultado a la propiedad ''loginIn'' en su constructor.
import { Injectable } from ''@angular/core'';
import { AngularFire } from ''angularfire2'';
import { Router } from ''@angular/router'';
@Injectable()
export class AuthService {
loggedIn: boolean = false;
constructor(
public af: AngularFire,
public router: Router) {
af.auth.subscribe(user => {
if(user){
this.loggedIn = true;
}
});
}
}
El problema aquí es obviamente asincrónico. CanActivate () de AuthGuard siempre devuelve un valor falso porque la suscripción no recibe los datos a tiempo para cambiar ''logIn'' a verdadero.
¿Cuál es la mejor práctica para solucionar esto?
EDITAR:
Cambiado el AuthGuard para devolver un observable.
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return this.af.auth.map((auth) => {
if (!auth) {
this.router.navigateByUrl(''login'');
return false;
}
return true;
});
}
Funciona, ya que no se redirige al inicio de sesión ... Pero el componente AuthGuarded de destino no se procesa.
No estoy seguro de si tiene que ver con mis app.routes. Este es el código para esa parte:
const routes: Routes = [
{ path: '''', component: MainComponent, canActivate: [AuthGuard] },
...
];
export const routing = RouterModule.forRoot(routes);
Para las versiones más recientes de AngularFire
, tienes que usar authState
en authState
lugar:
@Injectable()
export class AuthGuard implements CanActivate {
constructor(
private afAuth: AngularFireAuth,
private router: Router
) {}
canActivate(): Observable<boolean> {
return this.afAuth.authState
.take(1)
.map(authState => !!authState)
.do(auth => !auth ? this.router.navigate([''/login'']) : true);
}
}
No olvide importar take
, map
y do
desde rxjs/add/operator
.