AngularFire2:Observable 的问题
Posted
技术标签:
【中文标题】AngularFire2:Observable 的问题【英文标题】:AngularFire2: Issues with Observable 【发布时间】:2018-10-26 09:01:02 【问题描述】:我正在尝试根据用户是否具有管理员状态 (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
admin-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;
【问题讨论】:
【参考方案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】:您收到错误是因为您使用的是Array.map
而不是 rxjs 映射。您必须使用 pipe
的新语法
canActivate(): Observable<boolean>
return this.auth.user$.pipe(
switchMap(user => this.userService.get(user.uid))
.pipe(
map(appUser => appUser.isAdmin)
)
);
【讨论】:
你好。感谢您的帮助。我进行了更改,但现在出现以下错误:(由于空间有限,请参阅下面的答案)【参考方案3】:感谢 user4807496,他们的解决方案对我有用,我发现主要区别在于在 get(user.uid)
之后添加 valueChanges()
但是,我的基于最新版本的 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)
);
【讨论】:
以上是关于AngularFire2:Observable 的问题的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 angularfire2 valuechanges 方法获取随机数据
Firestore:将 angularfire2 异步数据传递为 Ionic 3 navParams 不起作用
如何为 Subject RxJS observable 分配初始值?
使用 Typescript 在服务中链接 observable 并最终在组件中订阅
Angular 2 Firebase Observable 承诺不会返回任何东西
具有嵌套 Observable/FirebaseObjectObservable 的 Angular2 ngFor 在更新时闪烁一些数据