Angular 5,Firestore,OAuth - 在组件

时间:2018-02-10 15:12:39

标签: angular typescript firebase-authentication rxjs google-cloud-firestore

我有以下问题

获得AuthService.ts,我使用Google帐户验证我的用户身份。在同一服务中,我将用户详细信息发送到Firestore数据库,例如uid,email等。

现在。在一个组件中,我需要从已登录的用户那里获取该uid,因此在构造函数中我已经定义了我的AuthService并尝试获取uid。

当我选择this.auth.user.subscribe(user => console.log(user.uid));它似乎有效 - >控制台记录了uid。

但是,当我尝试将其分配给变量和控制台日志/使用变量时,它会出现undefined错误。

以下是代码:

this.auth.user.subscribe(user => this.userDoc = this.afs.doc(用户/ $ {user.uid} )); this.user = this.userDoc.valueChanges(); console.log(this.user);

我做错了什么?

这是我的组件代码:

import { Component, OnInit } from '@angular/core';
import {AngularFirestore, AngularFirestoreDocument} from 'angularfire2/firestore';
import {Observable} from 'rxjs/Observable';
import {AuthService} from '../core/auth.service';

@Component({
  selector: 'app-judge-dashboard',
  templateUrl: './judge-dashboard.component.html',
  styleUrls: ['./judge-dashboard.component.css']
})


export class JudgeDashboardComponent implements OnInit {

  // entryDoc: AngularFirestoreDocument<any>;
  // entry: Observable<any>;
  userDoc: AngularFirestoreDocument<any>;
  user: Observable<any>;


  constructor(public auth: AuthService, private afs: AngularFirestore) { }

  ngOnInit() {
    this.auth.user.subscribe(user => console.log(user.uid)); //it works

    this.auth.user.subscribe(user => this.userDoc = this.afs.doc(`users/${user.uid}`));
    this.user = this.userDoc.valueChanges();
    console.log(this.user); // this one undefined
  }
}

AuthService:

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import * as firebase from 'firebase/app';
import { AngularFireAuth } from 'angularfire2/auth';
import { AngularFirestore, AngularFirestoreDocument } from 'angularfire2/firestore';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/switchMap';
import { User } from '../user';

@Injectable()
export class AuthService {

  user: Observable<User>;

  constructor(private afAuth: AngularFireAuth,
              private afs: AngularFirestore,
              private router: Router) {
    //// Get auth data, then get firestore user document || null
    this.user = this.afAuth.authState
      .switchMap(user => {
        if (user) {
          return this.afs.doc<User>(`users/${user.uid}`).valueChanges();
        } else {
          return Observable.of(null);
        }
      });
  }
  googleLogin() {
    const provider = new firebase.auth.GoogleAuthProvider();
    return this.oAuthLogin(provider);
  }
  private oAuthLogin(provider) {
    return this.afAuth.auth.signInWithPopup(provider)
      .then((credential) => {
        this.updateUserData(credential.user);
      });
  }
  private updateUserData(user) {
    // Sets user data to firestore on login
    const userRef: AngularFirestoreDocument<any> = this.afs.doc(`users/${user.uid}`);

    const data: User = {
      uid: user.uid,
      email: user.email,
      roles: {
        author: true
      },
      displayName: user.displayName || 'someDefaultValue',
      photoURL: user.photoURL
    };

    return userRef.set(data, { merge: true }); // without {merge:true} it will overwrite nor update.
  }
  signOut() {
    this.afAuth.auth.signOut().then(() => {
      this.router.navigate(['/']);
    });
  }
  ///// Abilities and Roles Authorizations
  ///// Assign roles to an ability method
  canRead(user: User): boolean {
    const allowed = ['admin', 'author', 'judge', 'partner'];
    return this.checkAutorization(user, allowed);
  }


  // determines if user has matching role
  private checkAutorization(user: User, allowedRoles: string[]) {
    if (!user) { return false; }
    for (const role of allowedRoles) {
      if ( user.roles[role] ) {
        return true;
      }
    }
    return false;
  }
}

即使我这样:

uid: string;
  ngOnInit() {
    this.auth.user.subscribe(user => {
      this.uid = user.uid;
      console.log(user.uid);
    });
    console.log(this.uid);

第一个控制台日志有效。第二个给出"undefined"

1 个答案:

答案 0 :(得分:3)

那是因为它是一种异步方法 考虑这个代码块:

ngOnInit() {
    this.auth.user.subscribe(user => {
      this.uid = user.uid;
      console.log(user.uid);
    });
    console.log(this.uid);
}

调用订阅用户obcervable, 然后调用第二个console.log(this.uid);,其中this.uid仍未定义) 然后当值被推入observable时,suscribe中的块被称为:

this.uid = user.uid;
console.log(user.uid);

这就是异步!