Access authenticated data with AngularFire2

2019-04-03 00:27发布

问题:

I am using AngularFire2 in an Angular2 project to do a very basic task, login and then show the logged in users information on the page.

The seemingly simple snag I've hit is that I need to know the users UID to request that data from Firebase (my permissions state can only access key inside "/users" with own UID - pretty standard).

I discovered in order to get the UID I need to subscribe to the af.auth observable and then inside there request the user data using af.auth.uid - which I've done successfully.

I've also noted that af.database.object creates another observable, which I can in theory access by piping with Asyc in my HTML. Issue is I can't seem to be able to get reference to the user's data obtained in the auth.subscribe, anywhere else in my App (specifically in the HTML).

I can console.log the subscribe of the user, which confirms I am getting the data.

Please correct my understanding or teach me how I can access this data, I am very very new to the concepts of Typescript and Observables.

Javascript Angular 2 Component

export class AppComponent {
  title = 'Webroot';
  user: FirebaseObjectObservable<any>;
  constructor(public af: AngularFire) {
    af.auth.subscribe(function(auth){
      if(auth != null){
        this.user = af.database.object("users/"+auth.uid)
        this.user.subscribe(user => console.log(user));
      }
      else{
        console.log("Auth is Null!")
      }
    });
  }
}

HTML

<div> {{ (user | async | json) }} </div>

回答1:

use arrow function => to preserve this keyword:

 export class AppComponent {
      title = 'Webroot';
      user: FirebaseObjectObservable<any>;
      constructor(public af: AngularFire) {
        af.auth.subscribe((auth)=>{
          if(auth != null){
            this.user = af.database.object("users/"+auth.uid)
            this.user.subscribe(user => console.log(user));
          }
          else{
            console.log("Auth is Null!")
          }
        });
      }
    }

you can do better :

 @Injectable()
  class UserService{
     constructor(private af: AngularFire) {}

     getUser(){
         return this.af.auth.switchMap((auth)=>{
            return this.af.database.object("users/"+auth.uid)
         });
     }
}



export class AppComponent {
      title = 'Webroot';
      user: FirebaseObjectObservable<any>;
      constructor(public userService: UserService) {
        this.userService
            .getUser()
            .subscribe(user => console.log(user));
      }
    }

use ChangeDetectorRef to force angular to update the view :

import { ChangeDetectorRef } from '@angular/core';

constructor(private af: AngularFire,public userService: UserService,private ref: ChangeDetectorRef) { }

 init(){
   this.userPublic = "Init";
   af.auth.subscribe((auth)=>{
          if(auth != null){
            this.getData(auth);
            this.userPublic = "Finish";
            this.ref.detectChanges(); 
          }
          else{
            //...
          }
        });

 }
}