【问题标题】:Angular2, Firebase, AngularFire2, route guard and how to deal with subscriptionAngular2、Firebase、AngularFire2、路由守卫以及如何处理订阅
【发布时间】:2016-10-12 05:51:41
【问题描述】:

我有一个现在可以使用的路由守卫,但我收到以下消息:

WARNING: the getAuth() API has changed behavior since adding support for Firebase 3.
    This will return null for the initial value when the page loads, even if the user is actually logged in.
    Please observe the actual authState asynchronously by subscribing to the auth service: af.auth.subscribe().
    The getAuth method will be removed in future releases

这是我现在的后卫:

import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { AngularFire, FirebaseListObservable, AuthProviders, AuthMethods } from 'angularfire2';
import {Observable} from "rxjs/Rx";

@Injectable()
export class AuthFirebaseGuard implements CanActivate {

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

  canActivate(route: ActivatedRouteSnapshot,
              state: RouterStateSnapshot){

    if (this.af.auth.getAuth().uid){
        return true;
    } else {
        this.router.navigate(['login']);
        return false;
    }

  }
}

这是我要更改的内容:

@Injectable()
export class AuthFirebaseGuard implements CanActivate {

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

  canActivate(route: ActivatedRouteSnapshot,
              state: RouterStateSnapshot){


    this.user = this.af.auth.subscribe(user => {
              if (user) {
                        this.user = user.auth.providerData[0];
                        if (user.auth.emailVerified==false){
                        user.auth.sendEmailVerification().then(function() {
                            this.router.navigate(['login']);
                            return false;
                        });
                        } else {
                           return true;
                        }
              }
              else {
                this.router.navigate(['login']);
                return false;
              }
            }); 
  }
}

如何等待订阅完成?

Class 'AuthFirebaseGuard' incorrectly implements interface 'CanActivate'.
  Types of property 'canActivate' are incompatible.
    Type '(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => void' is not assignable to type '(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => boolean | Observable<boolean> | Pr...'.
      Type 'void' is not assignable to type 'boolean | Observable<boolean> | Promise<boolean>'.








ERROR in [default] /Users/Documents/frontend/iboot/src/app/common/auth-firebase.gaurd.ts:14:13 
Class 'AuthFirebaseGuard' incorrectly implements interface 'CanActivate'.
  Types of property 'canActivate' are incompatible.
    Type '(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => Observable<{}>' is not assignable to type '(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => boolean | Observable<boolean> | Pr...'.
      Type 'Observable<{}>' is not assignable to type 'boolean | Observable<boolean> | Promise<boolean>'.
        Type 'Observable<{}>' is not assignable to type 'Promise<boolean>'.
          Property 'then' is missing in type 'Observable<{}>'.

ERROR in [default] /Users/Documents/frontend/iboot/src/app/common/auth-firebase.gaurd.ts:41:40 
Argument of type 'firebase.Promise<any>' is not assignable to parameter of type 'Promise<any>'.
  Types of property 'then' are incompatible.
    Type '(onResolve?: (a: any) => any, onReject?: (a: Error) => any) => Promise<any>' is not assignable to type '{ <TResult1, TResult2>(onfulfilled: (value: any) => TResult1 | PromiseLike<TResult1>, onrejected:...'.
      Type 'firebase.Promise<any>' is not assignable to type 'Promise<any>'.

【问题讨论】:

    标签: angular firebase firebase-authentication angularfire2


    【解决方案1】:

    canActivate 可以返回布尔值、promise 或 observable,因此您可以使用 AngularFire2 的 auth observable 组成一个 observable:

    canActivate(
      route: ActivatedRouteSnapshot,
      state: RouterStateSnapshot
    ) {
    
      return this.af.auth
    
        // Observables returned by canActivate have to complete, so take the
        // first emitted value from the auth observable.
    
        .first()
    
        // Use mergeMap to project the values emitted from the inner
        // observables created using Observable.fromPromise and
        // Observable.of. (If you weren't making the call to
        // sendEmailVerification, you could just use the map operator
        // and would return a boolean.)
    
        .mergeMap((user) => {
    
          if (user && user.auth) {
            if (!user.auth.emailVerified) {
              return Observable.fromPromise(user.auth
                .sendEmailVerification()
                .then(() => {
                  this.router.navigate(['login']);
                  return false;
                })
              );
            }
            return Observable.of(true);
          } else {
            this.router.navigate(['login']);
            return Observable.of(false);
          }
        });
    }
    

    【讨论】:

    • 我添加了尝试您的解决方案时收到的错误消息
    • 我取出了 .sendEmailVerification() 的逻辑,它起作用了。反正也不需要。谢谢!
    • 不用担心。该错误听起来像是鸭子类型承诺的 TypeScript 问题。你可以使用它来安抚 TypeScript:...sendEmailVerification().then(() =&gt; ... ) as Promise&lt;any&gt;
    猜你喜欢
    • 2019-03-26
    • 2017-07-21
    • 1970-01-01
    • 2019-02-04
    • 2018-12-04
    • 1970-01-01
    • 1970-01-01
    • 2018-11-14
    • 1970-01-01
    相关资源
    最近更新 更多