Как использовать массив ключей для запроса нескольких документов в Firestore

#javascript #reactjs #google-cloud-firestore

#javascript #reactjs #google-облако-firestore

Вопрос:

У меня есть веб-сайт, где пользователи могут посещать курсы. Когда пользователь начинает курс, я хочу добавить идентификатор курса к документу этого пользователя в firestore. На веб-сайте у пользователя есть своя страница профиля. В одном из разделов есть раздел «Курсы в процессе», где пользователи могут увидеть курс, на который они в данный момент записаны.

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

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

Я думаю, проблема в том, что документы курса возвращаются после отображения экрана.

Я пытался использовать async и await, чтобы убедиться, что код сначала завершает цикл и получает весь документ курса, чтобы затем он мог отображать их на экране, но это не работает.

Заранее большое спасибо за любую помощь

getEnrolledCareersList = async () => {

   let careersEnrolled = [];
  let careersEnrolledTemp = [];
  let careersEnrolledDocumentKeys = ["84YU2pLABF6qUvUEuwIm", "kwBaAUwkjTutGTcIKShw"];

 await careersEnrolledDocumentKeys.forEach((documentKey) =>{

      console.log("documentKey: ", documentKey);

      db.collection("...")
          .where("courseDocumentKey", "==", documentKey)
          .get()
          .then(
              (querySnapshot) => {
                  if (querySnapshot.empty) {
                      // doc.data() will be undefined in this case
                      console.log("No such document!");
                      return;
                  }

                  querySnapshot.forEach((doc) => {
                      console.log("getEnrolledCareersList Document data:", doc.data());
                      const {
                          courseName,
                          courseId,
                          coursePhotoUrl,
                          courseDocumentKey,
                      } = doc.data();

                      careersEnrolledTemp.push({
                          courseName,
                          courseId,
                          coursePhotoUrl,
                          courseKey: courseDocumentKey,
                      });
                  });
              },
              function(error) {
                  console.log("Error getting document Error: ", error);
              },
          );

  });
  

Компонент JSX:

 <div
          style={{
            // border: "solid #8492A6 5px",
            display: "flex",
            flexDirection: "column",
            //flexWrap: "wrap",
            justifyContent: "flex-start",
            padding: "0 0%",
          }}>

          {this.state.currentPaths.map((item, index) => (
            <div
              style={{
                display: "flex",
                flexDirection: "row",
                padding: "1% 1%",
              }}>
              <img
                alt={"career image"}
                src={item.coursePhotoUrl}
              />
              <div
                style={{
                    // border:"solid red 1px",
                  display: "flex",
                  flexDirection: "column",
                  justifyContent: "space-evenly",
                  padding: "0 2%",
                }}>

                  {/*Career Name Label*/}
                <label
                  style={{
                    // border: "solid  #8492A6",
                    textAlign: "center",
                  }}>
                  {item.courseName}
                </label>

                  {/*Career Percentage Completed Label*/}
                <label
                  style={{
                    // border: "solid  #8492A6",
                    textAlign: "center",
                  }}>
                  Percentage
                </label>
              </div>
            </div>
          ))}
        </div>
  

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

1. Вы захотите собрать обещания в массив и использовать Promise.all , чтобы дождаться их завершения, прежде чем двигаться дальше.

Ответ №1:

В итоге я сделал это, и это решило мою проблему. Друг помог мне получить это, а также большое спасибо @Doug Stevenson.

 getCourse = id => db.collection("abc")
    .doc(id)
    .get();

getEnrolledCareersList = async (courseIds = ["1", "2"]) => {
  const requests = courseIds.map(this.getCourse);
  const responses = await Promise.all(requests);
  const enrolledCourses = responses.map(doc => doc.data());
  this.setState({
      ...this.state,
      enrolledCourses,
  });
};