【问题标题】:AngularFire2: Issues with ObservableAngularFire2: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;
}

【问题讨论】:

    标签: javascript angular typescript firebase angularfire2


    【解决方案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)
         );
        }
      
      }
      

      【讨论】:

        猜你喜欢
        • 2019-01-17
        • 2017-03-11
        • 2018-08-29
        • 1970-01-01
        • 2018-08-22
        • 1970-01-01
        • 2018-08-01
        • 2023-04-05
        • 1970-01-01
        相关资源
        最近更新 更多