Angular Firebase: доступ к полевым картам для аутентификации - PullRequest
2 голосов
/ 14 марта 2019

У меня есть наборы пользователей Firebase> идентификатор документа> uid, ... и роли {admin: логический, модератор: логический, клиент: логический}. Мой процесс аутентификации работает правильно с защитниками, перенаправляющими по мере необходимости. Что еще более важно, я отображаю 90% данных в соответствующих компонентах на панели пользователя.

Проблема в том, что когда я ссылаюсь на {{user.roles.admin}}, используя ngIf в компоненте, я получаю ошибку:

ERROR TypeError: Cannot read property 'admin' of undefined at Object.eval [as updateRenderer]  

Забавно, что я не могу решить ни одну из проблем с игрой с кодом, чтобы попытаться получить информацию, но я могу настроить и отправить все, что захочу, обратно в Firebase. Мне нужен кто-то, чтобы указать мне правильное направление.

Модель:

export interface User {
  uid: string;
  email: string;
  photoURL?: string;
  displayName?: string;
  roles: Roles;
}

export interface Roles {
  admin?: boolean;
  moderator?: boolean;
  client?: boolean; 
}  

Служба авторизации:

import { Injectable, NgZone } from '@angular/core';
import { User } from "../../models/user/user";
import { auth } from 'firebase/app';
import { AngularFireAuth } from "@angular/fire/auth";
import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/firestore';
import { Router } from "@angular/router";
@Injectable({
  providedIn: 'root'
})
export class AuthService {
  userData: any; 
  constructor(
    public afs: AngularFirestore,   
    public afAuth: AngularFireAuth, 
    public router: Router,  
    public ngZone: NgZone 
  ) {    
    this.afAuth.authState.subscribe(user => {
      if (user) {
        this.userData = user;
        localStorage.setItem('user', JSON.stringify(this.userData));
        JSON.parse(localStorage.getItem('user'));
      } else {
        localStorage.setItem('user', null);
        JSON.parse(localStorage.getItem('user'));
      }
    })
  }
  SignIn(email, password) {
    return this.afAuth.auth.signInWithEmailAndPassword(email, password)
      .then((result) => {
        this.ngZone.run(() => {
          this.router.navigate(['account']);
        });
        this.SetUserData(result.user);
      }).catch((error) => {
        window.alert(error.message)
      })
  }
  ...
  ...
  ...
  get isLoggedIn(): boolean {
    const user = JSON.parse(localStorage.getItem('user'));
    return (user !== null && user.emailVerified !== false) ? true : false;
  }
  ...
  AuthLogin(provider) {
    return this.afAuth.auth.signInWithPopup(provider)
    .then((result) => {
       this.ngZone.run(() => {
          this.router.navigate(['account']);
        })
      console.log('User', result.user);
      this.SetUserData(result.user);
    }).catch((error) => {
      window.alert(error)
    })
  }
  SetUserData(user) {
    const userRef: AngularFirestoreDocument<any> = this.afs.doc(`users/${user.uid}`);
    const userData: User = {
      uid: user.uid,
      email: user.email,
      displayName: user.displayName,
      photoURL: user.photoURL,
      roles: {
        client: true
      }
    }
    return userRef.set(userData, {
      merge: true
    })
  }
  ...
}

1 Ответ

1 голос
/ 14 марта 2019

Вот как я проверяю пользователя в компоненте html:

*ngIf="user && user.role?.admin"

машинопись:

getUser() {
 this.authService.user$.subscribe(user => {this.user = user});
}

и это из службы аутентификации:

  user$: Observable<User>;
  authState: any = null;

  constructor (
    private afAuth: AngularFireAuth,
    private afs: AngularFirestore) {

    this.user$ = this.afAuth.authState.pipe(
      switchMap(user => {
        if (user) {
          return this.afs.doc<User>(`users/${user.uid}`).valueChanges();
        } else {
          return of(null);
        }
      })
    );
  }
...