Как ждать массив наблюдаемых от google-cloud-firestore - PullRequest
0 голосов
/ 11 июля 2019

Мы создаем приложение, в котором пользователь может создавать свои собственные цели или администратор может создать цель и назначить ее пользователю или группе пользователей.

Мы пытаемся отобразить имя пользователя, который создал конкретную цель в нашем приложении, учитывая цель, которую он создал. Каждая цель имеет поле, в котором хранится идентификатор пользователя, создавшего цель. Чтобы сделать это, мы попытались отобразить идентификаторы и имена пользователей в массиве, однако firestore возвращает данные как наблюдаемые. По какой-то причине функция возвращает пустой набор имен пользователей перед добавлением информации из базы данных в функцию подписки.

Таблица целей с созданным бланкомBy

  1. Мы пытались преобразовать информацию из базы данных в обещание, прежде чем добавить ее в наше приложение, но этот код не запускается.

  2. Мы также пытались дождаться данных после подписки на наблюдаемое, но код в конечном итоге возвращается до того, как код в функции подписки будет выполнен.

1

 async getUserNames(userIds: Array<string>) {
    const usersCollection = this.afs.collection<User>('users');
    const userNames = new Set();
    const reads = userIds.map(id => {
      const user$ = usersCollection.doc<User>(id).valueChanges();
      user$.toPromise().then(user => {
        console.log('adding user');
        userNames.add({
          id: user.uid,
          name: user.name
        });
      });
    });
    console.log(userNames);
    await Promise.all(reads);
    return Array.from(userNames.values());
  }
  1. async getUserNames(userIds: Array<string>) {
        const usersCollection = this.afs.collection<User>('users');
        const userNames = new Set();
        const reads = userIds.map(id => {
          // grab the user
          const user$ = usersCollection.doc<User>(id).valueChanges();
          user$.subscribe(user => {
            console.log('adding user');
            userNames.add({
              id: user.uid,
              name: user.name
            });
          });
        });
        await Promise.all(reads);
        console.log(userNames); // is empty because subscribe hasn't emitted
        return userNames;
      }
    

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

Чтобы воссоздать клон репозитория: https://github.com/ChadwickSchool/goal-management-angular/tree/goals-createdBy-error

git checkout goals-createdBy-error
npm install
ng serve -o

Нажмите кнопку «Домой», затем щелкните строку с именем «Анастасия», чтобы перейти на страницу, где возникает проблема.

1 Ответ

0 голосов
/ 16 июля 2019

Я считаю, что 1 не сработало, потому что вам нужно вернуть обещание на карте в этой строке: user$.toPromise().then(user => {

Вот моя версия 1, которая использует наблюдаемые до конца

async getUserNames(userIds: string[]) {
  const usersCollection = this.afs.collection<User>('users');
  const userNames = new Set();
  const reads = userIds.map(id => {
    return usersCollection.doc(id).get().pipe(
      tap(doc => {
        const { uid, name } = doc.data() as User;
        userNames.add({
          id: uid,
          name
        })
      })
    );
  });
  await forkJoin(reads).toPromise();
  return Array.from(userNames.values());
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...