我正在尝试根据用户是否具有状态admin(isAdmin = true)来保护URL。服务AdminAuthGuard通过调用服务UserService中的get(uid)函数来检查用户是否具有此管理状态。此get函数调用AppUser接口,该接口概述了相关字段。
使用AngularFire 2从Firebase数据库中检索数据。请参阅下面的版本详细信息。
我得到的错误是:
ERROR in src/app/admin-auth-guard.service.ts(21,17): error TS2345: Argument of type '(user: {}) => AngularFireObject<AppUser>' is not assignable to parameter of type '(value: {}, index: number) => ObservableInput<{}>'.
Type 'AngularFireObject<AppUser>' is not assignable to type 'ObservableInput<{}>'.
Type 'AngularFireObject<AppUser>' is not assignable to type 'Iterable<{}>'.
Property '[Symbol.iterator]' is missing in type 'AngularFireObject<AppUser>'.
src/app/admin-auth-guard.service.ts(21,51): error TS2339: Property 'uid' does not exist on type '{}'.
错误似乎引用的行是:
switchMap(user => this.userService.get(user.uid))
我的系统设置:
Angular CLI: 6.0.1
Node: 10.1.0
rxjs: 6.1.0
Firebase: 5.0.2
AngularFire2: 5.0.0-rc.8.0
管理-AUTH-guard.service.ts
import { Injectable } from '@angular/core';
import { CanActivate } from '@angular/router';
import { Observable } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { AuthService } from './auth.service';
import { UserService } from './user.service';
import { AppUser } from './models/app-user';
@Injectable({
providedIn: 'root'
})
export class AdminAuthGuard implements CanActivate {
constructor(private userService: UserService, private auth: AuthService) { }
canActivate(): Observable<boolean> {
return this.auth.user$.pipe(
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 { AppUser } from './models/app-user';
@Injectable({
providedIn: 'root'
})
export class UserService {
constructor(private db: AngularFireDatabase) { }
get(uid: string): AngularFireObject<AppUser> {
return this.db.object('/users/' + uid);
}
}
app-user.ts(用户模型)
export interface AppUser {
name: string;
email: string;
isActive: boolean;
}
答案 0 :(得分:1)
您收到错误是因为您使用的是Array.map
而不是rxjs地图。您必须将新语法与pipe
canActivate(): Observable<boolean> {
return this.auth.user$.pipe(
switchMap(user => this.userService.get(user.uid))
.pipe(
map(appUser => appUser.isAdmin)
)
);
}
答案 1 :(得分:1)
我在这里找到答案 Working with AngularFireObject and switchMap
canActivate(): Observable<boolean>{
return this.auth.user$
.pipe(switchMap(user => this.userService.get(user.uid).valueChanges()))
.pipe(map (appUser => appUser.isAdmin)); }
答案 2 :(得分:0)
感谢 user4807496,他们的解决方案对我有用,我看到主要区别在于在 valueChanges()
之后添加了 get(user.uid)
但是,我的基于最新版本的 angular 进行了一些修改,没有空字段。 为了确保您获取的内容不为空,您需要添加一个感叹号。
此外,您不需要将两个管道链接在一起,您可以简单地将 switchMap 和 map 放在一个管道中并用逗号分隔它们。 (在rxjs pipeable operators docs中查看更多)
export class AdminAuthGuardService implements CanActivate{
constructor(private auth: AuthService, private userService: UserService){ }
canActivate(): Observable<boolean> {
return this.auth.user$
.pipe(
switchMap( user => this.userService.get(user!.uid).valueChanges()),
map(appUser => appUser!.isAdmin)
);
}
}