Как использовать поле документа из одной коллекции, чтобы извлечь другое поле документа из другой коллекции? - PullRequest
0 голосов
/ 12 апреля 2020

Вот как структурирована моя база данных: таблица вызовов & таблица пользователей

Вот ошибка, которую я получаю: изображение ошибки

Я хочу использовать поле «create_by», которое также является идентификатором документа для таблицы пользователей, где я хочу получить как отображаемое имя, так и URL фотографии.

I'm Я не совсем уверен, как работают обещания, и у меня такое чувство, что я изо всех сил, но код, который у меня пока есть, приведен ниже:

Поиск данных:

UsersDao.getUserData(ChallengesDao.getChallenges().then(result => {return result['author'][0]})).then(result => {console.log(result)})

Проблемы DAO:

export default class ChallengesDao {

  static async getChallenges() {
const db = require('firebase').firestore();
    // const challenges = db.collection('challenges').limit(number_of_challenges)
    // challenges.get().then(())

    const snapshot = await db.collection('challenges').get()

    const names = snapshot.docs.map(doc => doc.data().name)
    const createdBy = snapshot.docs.map(doc => doc.data().created_by)
    const highScores = snapshot.docs.map(doc => doc.data().high_score.score)
    return {challengeName: names, author: createdBy, score: highScores}
  }

Пользователи DAO:

const db = require('firebase').firestore();

export default class UsersDao {
  static async getUserData(uid: string) {
    let userData = {};
    try {
      const doc = await db
        .collection('users')
        .doc(uid)
        .get();
      if (doc.exists) {
        userData = doc.data();
      } else {
        console.log('User document not found!');
      }
    } catch (err) {}
    return userData;
  }
}

1 Ответ

0 голосов
/ 12 апреля 2020

Вы приближаетесь. Все, что осталось сделать, - это вызвать getUserData для каждого UID, который вы получите от getChallenges.

. Комбинирование этих двух параметров будет выглядеть примерно так:

let challenges = await getChallenges();
let users = await Promise.all(challenges.author.map((uid) => getUserData(uid));

console.log(challenges.challengeName, users);

Новое здесь is Promise.all(), который объединяет несколько асинхронных вызовов и возвращает обещание, которое завершается, когда все они завершены.


Ваш код на первый взгляд кажется мне немного странным из-за способа, которым вы возвращаетесь данные из getChallenges. Вместо того, чтобы возвращать три массива с простыми значениями, я бы рекомендовал возвращать один массив, в котором каждый объект имеет три значения:

  static async getChallenges() {
    const db = require('firebase').firestore();
    const snapshot = await db.collection('challenges').get();

    const challenges = snapshot.docs.map(doc => { name: doc.data().name, author: doc.data().created_by, score: doc.data().high_score.score });

    return challenges;
  }

Если затем вы хотите добавить пользователя name к каждому объект в этом массиве, в дополнение к UID, который уже существует, вы можете сделать:

let challenges = await getChallenges();
await Promise.all(challenges.forEach(async(challenge) => {
  challenge.user = await getUserData(challenge.author);
});

console.log(challenges);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...