简体   繁体   English

AngularFire2:可观察的问题

[英]AngularFire2: Issues with Observable

I am trying to guard URLs based on whether the user has the status admin (isAdmin = true). 我正在尝试根据用户是否具有状态admin(isAdmin = true)来保护URL。 The service AdminAuthGuard checks whether the user has such admin status by calling the get(uid) function in the service UserService. 服务AdminAuthGuard通过调用服务UserService中的get(uid)函数来检查用户是否具有这种管理员状态。 This get function calls the AppUser interface that outlines the relevant fields. 此get函数调用概述相关字段的AppUser接口。

The data are retrieved from a Firebase database using AngularFire 2. See below for version details. 使用AngularFire 2从Firebase数据库检索数据。有关版本详细信息,请参见下文。

The errors that I'm getting are: 我得到的错误是:

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 '{}'.

The line that the errors seem the refer to is: 错误似乎指向的行是:

switchMap(user => this.userService.get(user.uid))

My system setup: 我的系统设置:

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 管理员认证- 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 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 (model for users) app-user.ts(用户模型)

export interface AppUser {
  name: string;
  email: string;
  isActive: boolean;
}

You are getting the error because you are using Array.map and not rxjs map. 您收到错误是因为您使用的是Array.map而不是rxjs map。 You have to use the new syntax with pipe 您必须对pipe使用新语法

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

I found answer here Working with AngularFireObject and switchMap 我在这里找到答案使用AngularFireObject和switchMap

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM