Вызов Firebase из облачной функции с angular / ioni c не может получить результат, но работает с curl - PullRequest
0 голосов
/ 09 марта 2020

Я разрабатываю небольшое приложение для проекта для класса, в котором я должен получить данные некоторых пользователей из firebase. Для этого я решил использовать облачную функцию для извлечения всех пользователей. Вот код моей функции.

import { Request, Response } from 'express';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
import * as cors from 'cors';
const corsHandler = cors({origin: true});

admin.initializeApp();

const getAllUsers = (req: Request, res: Response) => {
  corsHandler(req, res, () => {
    const maxResults = 1000; // optional arg.
    const allUsers: any = {'email': [], 'uid': []};
    admin.auth().listUsers(maxResults).then(
      (userRecords: { users: any[]; }) => {
        userRecords.users.forEach(userRecord => {
          // For each user
          allUsers['email'].push(userRecord.email);
          allUsers['uid'].push(userRecord.uid);
        });
        return res.status(200).send(JSON.stringify(allUsers));
      }).catch((error: any) => {
        console.log("Error listing users:", error);
        return res.status(500).send(error);
      });
  })
}

module.exports = {
  api: functions.https.onRequest(getAllUsers),
};

Проблема на стороне angular, я пытаюсь получить результат этой функции, если я использую curl, нет проблем, я получаю всю информацию Я нуждаюсь. Но когда я использую сервис angular, он застрял в бесконечном l oop. Вот мой код:

<p> {{ this.authService.getAllUsers() | async }}  </p>

В моем файле html я просто хочу напечатать результат и в моем сервисе:

  import { functions, auth } from 'firebase';

  getAllUsers(): Promise<any> {
    //return this.http.get('https://XXX.cloudfunctions.net/api').toPromise();
    return functions().httpsCallable('getAllUsers')();
  }

Как вы уже видели, я должен получить обещаю из этих двух результатов, чтобы я не знал, где может появиться бесконечное l oop. В консоли не вижу ошибок ...

Спасибо за помощь!

1 Ответ

2 голосов
/ 09 марта 2020

Попробуйте это в вашем auth.service.ts коде:

getAllUsers(): Observable<any> {
  return this.http.get('https://XXX.cloudfunctions.net/api');
}

в вашем компоненте ts:

  allUsers$: Observable<any>;

  ...

  ngOnInit() {
    this.allUsers$ = this.authService.getAllUsers();
  }

в шаблоне вашего компонента:

<p> {{ allUsers$ | async }}  </p>

async pipe автоматически подпишется на allUsers$ observable и доставит HTTP GET запрос к вашему Cloud function.

Важно : никогда не используйте функции внутри вашего шаблона и особенно с async pipe.

Из-за системы обнаружения изменений, Angular необходимо выполнить функцию, чтобы узнать, изменился ли ее результат.

В случае, если функция возвращает Observable с задержкой (запрос http, например), Angular подпишется на нее через канал async и инициирует новое время, когда обнаружение изменений будет пришло время перерисовать компонент, который создаст новую наблюдаемую через функцию ... бесконечно l oop следовательно.

См., например, этот вопрос .

Предложение по улучшению (напрямую не связано с проблемой):

Кроме того, лучше ввести ваш ответ, например:

getAllUsers(): Observable<ApiResponse> {
  return this.http.get<ApiResponse>('https://XXX.cloudfunctions.net/api');
}
...