Как выполнить несколько вложенных вызовов firebase в ngInit в приложении Ionic4 - PullRequest
1 голос
/ 13 мая 2019

У меня есть приложение Ionic4 / Angular, подключенное к магазину Firebase.У меня работает аутентификация Firebase и я могу получить данные Firebase для заполнения массива.Но когда дело доходит до поиска значения из одной таблицы Firebase и последующего использования поля из возвращенного документа для просмотра другой таблицы, я сталкиваюсь с кирпичными стенами.Я пытаюсь найти запись пользователя из auth.currentuser.uId и вернуть документ, чтобы я мог извлечь другие значения поля.

Я создал службу для извлечения пользователей (отдельная таблица Firebase)встроенной аутентификации для предоставления информации профиля) и другой сервис для извлечения записей Drama (другая таблица Firebase).В рамках ngInit я успешно извлекаю записи Drama через этот сервис и отображаю их на странице, хотя это просто возвращает все записи.Мой призыв вернуть пользователя с помощью запроса не работает.

Вот мой сервис Drama

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;
    });
  }
}

вот сервис пользователя ...

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();
  }
}

и вот исправленная страница, вызывающая getUser (id), которая не работает ...

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;
    });
  }
}

В консоли я получаю: "core.js: 15724ОШИБКА TypeError: Невозможно прочитать свойство 'collection' of undefined ", что заставляет меня думать, что я неправильно объявляю или инициализирую свой экземпляр AngularFireStore.Но этот подход используется в конструкторе сервисов, который работает.

getUser(id) { 
    let db: AngularFirestore;
    this.usersCollection = db.collection<User>('Users', ref => ref.where('userId', '==', id)); //undefined error here
    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;
  }

1 Ответ

1 голос
/ 13 мая 2019

Это происходит потому, что вы пропустили объявление DependencyInjection(DI) против variable.

В DramaService у вас есть injected (DI) экземпляр 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 };
        });
      })
    );
  } 

где, как и в UserService , вы объявили db переменную типа AngularFirestore, но никогда не присваивали никакого значения, поэтому undefined может быть изменяемым.

  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;
  }

Попробуйте в UserService :

  constructor(private db: AngularFirestore) {
    this.usersCollection = this.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 };
        });
      })
    );
  }

в getUser (id)


  getUser(id) { 
    this.usersCollection = this.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;
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...