Почему я не могу получить данные из DocumentReference в firebase?

#javascript #firebase

#javascript #firebase

Вопрос:

У меня есть привычка содержать ссылку на элемент в коллекции категорий. Я хочу прочитать данные из него. Но он продолжает выдавать мне такой результат. Я пытался так много раз, но я все еще не могу этого сделать:

 {
    "id": "3TFzK0bvzGsZJyM2IkI2",
    "name": "Pushup",
    "description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic ",
    "imageUrl": "https://i.pinimg.com/564x/f5/46/30/f54630a64c48966b9cf803838c34c313.jpg",
    "categories": {},
    "createdAt": {
        "seconds": 1602046800,
        "nanoseconds": 0
    }
}
  

Ожидаемый результат:

 {
    "id": "3TFzK0bvzGsZJyM2IkI2",
    "name": "Pushup",
    "description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic ",
    "imageUrl": "https://i.pinimg.com/564x/f5/46/30/f54630a64c48966b9cf803838c34c313.jpg",
    "categories": {

    "id": "3TFzK0bvzGsZJyM2IkI2",
    "name": "Pushup",
    "createdAt": {
        "seconds": 1602046800,
        "nanoseconds": 0
    }

},
    "createdAt": {
        "seconds": 1602046800,
        "nanoseconds": 0
    }
}
  

Вот мой код:

 db.collection("habits")
.get()
.then((data) => {
  let habits = [];
  data.forEach((doc) => {
    let singleRow = doc.data();
    let habit = {
      id: doc.id,
      name: singleRow.name,
      description: singleRow.description,
      imageUrl: singleRow.imageUrl,
      categories: {},
      createdAt: singleRow.createdAt,
    };

    if (singleRow.categories) {
      singleRow.categories
        .get()
        .then((res) => {
          habit.categories = res.data();
          return;
        })
        .catch((err) => console.log(err));
    }

    habits.push(habit);
  });
  return res.json(habits);
})
.catch((err) => {
  console.error(err);
  return res.status(500).json({ message: "Something went wrong...!" });
});
  

Пожалуйста, помогите мне! Большое спасибо …!

Комментарии:

1. Каким должен быть результат?

2. Я хочу иметь это в категориях: {«id»: «3TFzK0bvzGsZJyM2IkI2», «name»: «Pushup», «createdAt»: { «секунды»: 1602046800, «наносекунды»: 0 }}

3. Пожалуйста, добавьте это в свой вопрос, а не в качестве комментария.

Ответ №1:

при том, как это написано, ваш код не будет ждать, пока обещание, возвращенное из singleRow.categories.get() , разрешится, прежде чем habit вводить habits , а затем возвращаться res.json(habits) , когда цикл foreach завершается. Вместо этого вы могли бы использовать async / await вместе с Promise.all подобным образом:

 db.collection("habits")
.get()
.then(async (querySnapshot) => {
  // use Promise.all to wait for all promises in array to resolve or reject.
  const habits = await Promise.all(querySnapshot.docs.map(async (doc) => {
    // map over data to convert each doc into a promise that will resolve to the value of the habit object.
    const singleRow = doc.data();
    const habit = {
      id: doc.id,
      name: singleRow.name,
      description: singleRow.description,
      imageUrl: singleRow.imageUrl,
      categories: {},
      createdAt: singleRow.createdAt,
    };
    if (singleRow.categories) {
      try {
        // wait for the promise returned from singleRow.categories.get(), then set habit.categories using resolved value
        const res = await singleRow.categories.get()
        habit.categories = res.data();
      } catch (err) {
        console.log(err);
      }
    }
    return habit
  }))
  return res.json(habits);
})
.catch((err) => {
  console.error(err);
  return res.status(500).json({ message: "Something went wrong...!" });
});  

Комментарии:

1. Я отредактирую свой ответ, чтобы дать более подробную информацию, будьте готовы…

2. в нем говорилось: «data.map не является функцией»

3. хм, хорошо, это, вероятно, что-то с возвращаемым значением из db.collection(‘habits’).get() . Я предположил, что это массив, поскольку вы использовали forEach его в своем вопросе. но, возможно, есть еще один шаг для получения массива документов.

4. похоже, что db.collection(‘habits’).get() возвращает querySnapshot , на который вы затем должны ссылаться .docs перед вызовом .map. обновит мой ответ, чтобы отразить это.