Angular 2 - 观察firebase数据库的结果

时间:2017-06-08 19:54:25

标签: angular typescript angular2-services

我是棱角分明的新人,所以要善良:)

Angular 2(1.0.4) Angular Cli NodeJs 7.9

我尝试制作一个集中服务,检查用户是否已登录,如果它是反向的并发回用户数据...我只是尝试2天,使此方法无效成功..任何帮助将不胜感激:

    import { Injectable } from '@angular/core';
    import { Component, OnInit } from '@angular/core';
    import { AngularFireAuth } from 'angularfire2/auth';
    import { AngularFireDatabaseModule, AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database';
    import { Observable } from 'rxjs/Rx';
    import { TipoUtente } from './tipidati' ;
    import {Resolve, ActivatedRouteSnapshot, RouterStateSnapshot, Router} from '@angular/router';

    import * as firebase from 'firebase';

    import 'rxjs/add/operator/toPromise' ;


    @Injectable()
    export class StatoutenteService implements OnInit {

constructor(private db: AngularFireDatabase, private afAuth: AngularFireAuth, private router: Router) {}

public getUserData() : Observable<any> {

  this.afAuth.authState.map( auth => {

        if (auth == null) {
          this.Logged = false ;
          this.Utente = new TipoUtente() ;
          this.UId = '' ;
          return undefined ;

        } else {
          this.Logged = true  ;
          this.UId = auth.uid ;

          return this.dbUserData().then(data => {
              console.log('leggo promessa') ;
              console.log(data) ;
              if (data.Livello != undefined) this.Utente = data ; else this.Utente = undefined ;
              console.log(this.Utente) ;
              if ( this.Utente == undefined ) { this.createNewUser() }
            } ) ;
        }
      } ) ;


} ;

private dbUserData() : Promise<TipoUtente> {

  // Controllo Utente
  console.log('Recupero dati utente!') ;
  console.log('UID :' + this.UId ) ;
  console.log(this.Logged) ;

  let utenteX = this.db.object('users/' + this.UId)
  return new Promise((resolve, reject) => {
    // must import 'rxjs/add/operator/first'; before using it here
    utenteX.subscribe( data  => {
      if ( data.$value == null ) resolve(undefined); else resolve(data) ;
    }, reject);
  });

}

2 个答案:

答案 0 :(得分:0)

主要问题是你的getUserData()没有返回任何内容。你需要返回ovservable。

return this.afAuth.authState.map( auth => { ....

然后您应该能够通过订阅getUserData()来访问userData:

this.statoutenteService.getUserData().subscribe(promisedUserData => {...})

但实际上混合承诺和观察不是一个好习惯。试着像这样重新构建它:

export class StatoutenteService implements OnInit {
    Logged: boolean;
    UId: string;
    Utente: TipoUtente;

    constructor(private db: AngularFireDatabase, private afAuth: AngularFireAuth, private router: Router) {
         this.Logged = false;
         this.UId = '';
         this.Utente = new TipoUtente();
    }

    public getUserData() : Observable<any> {

      return this.afAuth.authState
         .filter(auth => !!auth)  //filters out events where auth is not truthy
         .flatMap( auth => {      //flatMap will resolve the returned observable (chaining observables)
             this.Logged = true;
             this.UId = auth.uid;

             return this.db.object('users/' + this.UId);
        }).map(data => {
             if (data.Livello != undefined)  
                 this.Utente = data; 
             else 
                 this.Utente = undefined;
             console.log(this.Utente) ;
             if (this.Utente == undefined)  
                 return this.createNewUser();
             return null; 
        });
    }
}

然后你没有承诺的开销。然后,当您订阅getUserData()observable时,您将获得最后一个maping函数返回的内容。所以你现在得到this.createNewUser()的返回值;如果this.Utente之前未定义。否则为空。

您可以通过订阅它来以相同的方式访问它:

this.statoutenteService.getUserData().subscribe(user => {...})

希望能帮助你。

答案 1 :(得分:-1)

你好,谢谢你的答案:)我只是为我编辑了一些作品,现在效果要好得多。那么我以前的代码(感谢!!)

我现在只需要听取一个&#34;空&#34;用户什么时候不是auth ...我尝试编辑你的代码,但我得到了一个例外。

所以我尝试制作这个架构:

  1. 菜单栏调用服务请求UserData
  2. 如果用户被记录:菜单栏根据等级
  3. 获取用户数据和更新按钮
  4. 如果用户未被记录:菜单栏显示&#34;登录&#34;按钮和隐藏菜单。
  5. 到目前为止,这是编辑过的代码:

    服务:

          public getUserData() : Observable<any> {
    
            return this.afAuth.authState
               .flatMap( auth => {      //flatMap will resolve the returned observable (chaining observables)
                   if ( auth == null ) {
                     this.Logged = false;
                     return undefined ;  // <<< Angular doesn't like this because it expect a stream
                   } else {
                   this.Logged = true;
                   this.UId = auth.uid;
                   return this.db.object('users/' + this.UId);
                   }
              }).map(data => {
                   console.log('sono dentro data') ;
                   console.log(data) ;
                   if (data.Livello != undefined) {
                       console.log('sono dentro if') ;
                       this.Utente = data;
                   } else {
                       this.Utente = undefined; }
                   console.log(this.Utente) ;
                   if (this.Utente == undefined) return this.createNewUser(); else return data ;
              });
          }
    
    private createNewUser() : Observable<any> {
    
      // Creo utente
      console.log('Creo Utente!') ;
      console.log(this.Logged) ;
    
      // se non sono loggato ritorno Livello 0
      if ( !this.Logged ) { return undefined } ;
    
      // carico dati in Utente :
      this.afAuth.authState.subscribe(auth => {
        if (auth != undefined) {
        console.log('sono in MAP') ;
      this.Utente = new TipoUtente() ;
      this.Utente.Cognome = auth.displayName.split(" ")[0] ;
      this.Utente.Nome    = auth.displayName.split(" ")[1] ;
      this.Utente.DisplayName = auth.displayName ;
      this.Utente.Immagine = auth.photoURL ;
      this.Utente.Livello = 1 ;
      this.UId = auth.uid ;
    
      // scrivo utente :
      console.log('chiamo DB') ;
    
      return this.db.database.ref('users/' + auth.uid).set(this.Utente) ;
      }
    }) ;
    

    MENUBAR:

    this.StatoUtente.getUserData().subscribe(data => {
    
        this.Utente = data ;
        console.log(data) ;
    
        if ( data != undefined ) {
            this.btntext = "Accedi" ;
            this.LevelMenu = 0 ;
            this.router.navigateByUrl('/') ;
    
          } else {
            this.btntext = "Logout" ;
    
            this.Utente = data ;
            this.LevelMenu = this.Utente.Livello ;
          }
        })