如何在Ionic4应用程序的ngInit中执行多个嵌套的Firebase调用

时间:2019-05-13 06:29:33

标签: angular firebase ionic-framework

我有一个Ionic4 / Angular应用程序连接到Firebase商店。我具有Firebase身份验证功能,可以检索Firebase数据以填充阵列。但是,当涉及到从一个Firebase表中查找值,然后使用返回的文档中的字段来查找另一张表时,我遇到了麻烦。我想做的是从auth.currentuser.uId中查找用户记录,然后返回文档,以便提取其他字段值。

我已经创建了一个用于检索Users的服务(与内置身份验证分开的Firebase表以提供配置文件信息),以及一个用于检索Drama的服务(另一个Firebase表)。在ngInit中,我通过该服务成功检索了Drama记录并将其显示在页面上,尽管这只是返回所有记录。我通过查询返回用户的调用不起作用。

这是我的戏剧服务

f('blue', 'y') = if 'blue' in `color attribute` column of DB and words previous to 'blue' is in `product attribute` column of DB and 'y' is `colors` then return 1 else 0.

,此调用在页面中按预期工作

import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection } from '@angular/fire/firestore';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

export interface Drama {
  id?: string;
  dramaName: string;
  image: string;
  groupId: string;
}

@Injectable({
  providedIn: 'root'
})
export class DramaService {
  private dramasCollection: AngularFirestoreCollection<Drama>;

  private dramas: Observable<Drama[]>;

  constructor(db: AngularFirestore) {
    this.dramasCollection = db.collection<Drama>('Drama');

    this.dramas = this.dramasCollection.snapshotChanges().pipe(
      map(actions => {
        return actions.map(a => {
          const data = a.payload.doc.data();
          const id = a.payload.doc.id;
          return { id, ...data };
        });
      })
    );
  } 

  getDramas() {
    return this.dramas;
  }

  getDramasByGroup(groupId: string) {
    return this.dramas;
  }

  getDrama(id) {
    return this.dramasCollection.doc<Drama>(id).valueChanges();
  }

  updateDrama(drama: Drama, id: string) {
    return this.dramasCollection.doc(id).update(drama);
  }

  addDrama(drama: Drama) {
    return this.dramasCollection.add(drama);
  }

  removeDrama(id) {
    return this.dramasCollection.doc(id).delete();
  }
}

这是用户服务...

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Drama, DramaService } from '../services/dramas.service'

@Component({
  selector: 'app-drama',
  templateUrl: './drama.page.html',
  styleUrls: ['./drama.page.scss']
})

export class DramaPage implements OnInit {

  dramas: Drama[];

  constructor(
    public globalService: GlobalService,
    private router: Router,
    private dramaService: DramaService) {}

  ngOnInit() {
    this.dramaService.getDramas().subscribe(res => {
    this.dramas = res;
    });
  }
}

这是修改后的页面,调用getUser(id)无效...

import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection } from '@angular/fire/firestore';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { defineBase } from '@angular/core/src/render3';
import * as firebase from 'firebase';

export interface User {
  id?: string;
  firstName: string;
  lastName: string;
  email: string;
  groupId: string;
  userId: string;
}

@Injectable({
  providedIn: 'root'
})

export class UserService {
  private usersCollection: AngularFirestoreCollection<User>;

  private users: Observable<User[]>;

  constructor(db: AngularFirestore) {
    this.usersCollection = db.collection<User>('Users');

    this.users = this.usersCollection.snapshotChanges().pipe(
      map(actions => {
        return actions.map(a => {
          const data = a.payload.doc.data();
          const id = a.payload.doc.id;
          return { id, ...data };
        });
      })
    );
  }

  getUsers() {
    return this.users;
  }

  getUser(id) { 
    let db: AngularFirestore;
    this.usersCollection = db.collection<User>('Users', ref => ref.where('userId', '==', id));
    this.users = this.usersCollection.snapshotChanges().pipe(
      map(actions => {
        return actions.map(a => {
          const data = a.payload.doc.data();
          const id = a.payload.doc.id;
          return { id, ...data };
        });
      })
    );
    return this.users;
  }

  updateUser(user: User, id: string) {
    return this.usersCollection.doc(id).update(user);
  }

  addUser(user: User) {
    return this.usersCollection.add(user);
  }

  removeUser(id) {
    return this.usersCollection.doc(id).delete();
  }
}

在控制台中,我得到:“ core.js:15724错误TypeError:无法读取未定义的属性'collection'”,这使我认为我没有正确地声明或初始化AngularFireStore实例。但这是在服务构造函数中有效的方法。

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Drama, DramaService } from '../services/dramas.service';
import { User, UserService } from '../services/users.service';
import { AngularFireAuth } from '@angular/fire/auth';

@Component({
  selector: 'app-drama',
  templateUrl: './drama.page.html',
  styleUrls: ['./drama.page.scss'],
  providers: [GlobalService]
})

export class DramaPage implements OnInit {

  dramas: Drama[];
  user: User[];
  uid: string;

  constructor(
    public globalService: GlobalService,
    private router: Router,
    private dramaService: DramaService,
    private userService: UserService,
    public afAuth: AngularFireAuth) {}

  ngOnInit() {
//this call doesn't work
    this.afAuth.authState.subscribe(authUser => {
      if (authUser){
        console.log('drama page authUser: ', authUser.uid);
        this.userService.getUser(authUser.uid).subscribe(res => {
          this.user=res;
          console.log(this.user);
        });
      }
    })

    this.dramaService.getDramas().subscribe(res => {
    this.dramas = res;
    });
  }
}

1 个答案:

答案 0 :(得分:1)

之所以发生,是因为您忽略了.Net CoreDependencyInjection(DI)声明。

DramaService 中,您在构造函数中具有variable的{​​{1}}(DI)实例为:

injected

UserService 中,您已经声明了AngularFirestore类型的 constructor(db: AngularFirestore) { this.dramasCollection = db.collection<Drama>('Drama'); this.dramas = this.dramasCollection.snapshotChanges().pipe( map(actions => { return actions.map(a => { const data = a.payload.doc.data(); const id = a.payload.doc.id; return { id, ...data }; }); }) ); } 变量,但从未分配任何值,因此它是一个db变量。

AngularFirestore

尝试使用 UserService

undefined

在getUser(id)

  getUser(id) { 
    let db: AngularFirestore; // <-- declaration but no initialization.
    this.usersCollection = db.collection<User>('Users', ref => ref.where('userId', '==', id));
    this.users = this.usersCollection.snapshotChanges().pipe(
      map(actions => {
        return actions.map(a => {
          const data = a.payload.doc.data();
          const id = a.payload.doc.id;
          return { id, ...data };
        });
      })
    );
    return this.users;
  }