错误TS2345 Angular AngularFire2检查用户是否为admin

时间:2017-11-21 20:42:48

标签: angular angularfire2

尝试使用最新版本的Firebase和Angular。我想要实现的总体概念是管理员身份验证。我已经实现了登录注销功能。我已使用UID将googleAuth登录用户保存到数据库。现在我要做的是将一些页面限制为登录和管理员。所以我已经将isAdmin:true指定为存储在数据库中的用户对象中的值。基本上我想查看用户是否为admin并为路由器参数返回true或false。我一直在使用Angular和Firebase。我认为自己是初学者。我不太明白如何从AngularFire2 4迁移 - > AngularFire 5。 我得到的当前错误是TS2345:

ERROR in src/app/admin-auth-guard.service.ts(15,38): error TS2345: Argument of type '(user: User) => AngularFireObject<AppUser>' is not assignable to parameter of type '(value: User, index: number) => ObservableInput<{}>'.
  Type 'AngularFireObject<AppUser>' is not assignable to type 'ObservableInput<{}>'.
    Type 'AngularFireObject<AppUser>' is not assignable to type 'ArrayLike<{}>'.
      Property 'length' is missing in type 'AngularFireObject<AppUser>'.

从我认为我理解get函数返回一个Object,但错误是期望一个observable。我所知道的关于可观察物的是你可以订阅它们而你应该销毁它们......

我需要使用当前登录的用户ID来查询数据库并返回与uid匹配的用户对象,然后检查isAdmin是true还是false。然后将其返回到路径参数,以便我可以将页面限制为Authenticated和Admin。

请指出正确的方向。

管理员-AUTH-guard.service.ts

import { Injectable } from '@angular/core';
import { CanActivate } from '@angular/router';
import { AuthService } from './auth.service';
import { UserService } from './user.service';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/map';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class AdminAuthGuardService implements CanActivate {

  constructor(private auth: AuthService, private userService: UserService) { }

  canActivate(): Observable<boolean> {
    return this.auth.user$.switchMap(user => this.userService.get(user.uid)).map(appUser => appUser.isAdmin);
  }

}

user.service.ts

import { Injectable } from '@angular/core';
import { AngularFireDatabase, AngularFireObject } from 'angularfire2/database';
import * as firebase from 'firebase';
import { Observable } from 'rxjs/Observable';
import { AppUser } from './models/app-user';

@Injectable()
export class UserService {

  constructor(private db: AngularFireDatabase) { }

  save(user: firebase.User) {
    this.db.object('/users/' + user.uid).update({
      name: user.displayName,
      email: user.email
    });
  }

  get(uid: string): AngularFireObject<AppUser> {
    return this.db.object('/users/' + uid);
  }

}

这是我一直在寻求帮助的地方:https://github.com/angular/angularfire2/blob/master/docs/version-5-upgrade.md

我不明白注释如何对创建的函数完全起作用。从这个引用“observable”我假设意味着这个canActivate()函数从一个Observable扩展而且应该返回一个布尔值(true / false)。

感谢您的时间。

9 个答案:

答案 0 :(得分:7)

 get(uid: string): Observable<any> {
    return this.db.object('/users/' + uid).valueChanges();
 }

并且:

canActivate(): Observable<boolean> {
   return this.auth.user$.switchMap(user => 
   this.userService.get(user.uid)).map((appUser :any) => appUser.isAdmin);
}

有关详细信息,请参阅:info

答案 1 :(得分:2)

就我而言,它有效 AdminAuthGuard服务。

import { Injectable } from '@angular/core';
import { CanActivate } from '@angular/router';
import { AuthService } from './auth.service';
import { map, switchMap } from 'rxjs/operators';
import { Observable } from 'rxjs';
import { UserService } from './user.service';
import * as firebase from 'firebase';

@Injectable()
export class AdminAuthGuard implements CanActivate {

  constructor(private auth: AuthService,
  private userService: UserService) {}

  canActivate(): Observable<boolean> {
    return this.auth.user$.pipe(switchMap((user: firebase.User) =>
      this.userService.get(user.uid)).
      map((appUser) => appUser.isAdmin));
   }

}

<强> UserService.ts

 get(uid: string): Observable<any> {
    return this.db.object('/users/' + uid).valueChanges();
 }

答案 2 :(得分:1)

AdminAuthGuard服务。

apiVersion: v1
kind: DeploymentConfig
metadata:
  name: myservice
  generation: 1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: example
    spec:
      containers:
      - name: myservice
        image: myorg/myimage:mytag
        imagePullPolicy: Always
        ports:
        - containerPort: 8888

UserService.ts

 canActivate(): Observable<boolean> {
 return this.auth.user$
 .switchMap(user => this.userService.get(user.uid).valueChanges())
 .map(appUser => appUser.isAdmin);
 }    

答案 3 :(得分:0)

user.service.ts

get(uid: string): Observable<any> {
return this.db.object('/users/' + uid).valueChanges();
}

admin-auth-guard.service.ts

canActivate(): Observable<boolean> {
return this.auth.user$.pipe(switchMap(user => this.userService.get(user.uid).pipe(map((appUser: any) => appUser.isAdmin))));
}

答案 4 :(得分:0)

将“ FirebaseObjectObservable”替换为“ Observable”,然后从rxjs导入

从'rxjs'导入{Observable};

答案 5 :(得分:0)

Admin-auth-guard.service.ts

canActivate(): Observable<boolean> {
     return this.auth.user$
    .pipe(switchMap(user=> {
        return this.userService.get(user.uid).valueChanges()
        }),
        map(appUser=> appUser.isAdmin));
  }


user.service.ts

get(uid: string): AngularFireObject<AppUser>{
    return this.db.object('/users/'+ uid);
  }

答案 6 :(得分:0)

我在角度8中尝试了上述方法,但没有任何效果。请从用户服务中删除get方法并实现以下代码。

canActivate(): Observable<boolean>{
    return this.authService.user$.pipe(
      switchMap((user: firebase.User) => this.db.object('/user/'+ user.uid).valueChanges()),
      map((user: AppUser) =>  user.isAdmin))
}

答案 7 :(得分:0)

只有这样,我才能使用角度8:

canActivate(): Observable<boolean> {
    return this.auth.user$.pipe(
        switchMap((user: firebase.User) =>
        this.userService.get(user.uid)
        .pipe(
          map((appUser) => appUser.isAdmin)
        )
      )
    )
  }

和UserService获取方法

get(uid: string): Observable<any> {
    return this.db.object('/users/' + uid).valueChanges();
}

答案 8 :(得分:0)

admin-auth-guard.service.ts

canActivate(): Observable<boolean> {
    return this.auth.user$
    .pipe(switchMap(user=> this.userService.get(user.uid).valueChanges()),
    map(appUser=> appUser.isAdmin));
 }

user.service.ts

get(uid: string): AngularFireObject<AppUser>{
  return this.db.object('/users/'+ uid);
}

它可以像下面这样完成,并且可以直接映射,因为它们都是可观察的。但是在最新版本的angular中不推荐使用FirebaseObjectObservable。

get(uid: string): FirebaseObjectObservable<AppUser>{
      return this.db.object('/users/'+ uid);
    }

因此,当我们使用AngularFireObject时,我们必须执行.valueChanges(),然后它将返回一个可观察的对象,以便最终可以在canActivate()中返回一个布尔的可观察的对象