在服务器端使用 firebase/firestore 获取多个数据 (nextjs/apiRoutes) =problem => 在数据准备好之前输出

fetching multiple data using firebase/firestore on the server side (nextjs/apiRoutes) =problem => output before the data is ready

结果[]将在数据准备好之前执行。我什至尝试用 promise 解决问题,但也没有成功..

import { firestore } from "../../../firebase";

export default (req, res) => {
  firestore
    .collection("category-filters")
    .where(req.query.categoryKey, "==", true)
    .get()
    .then(querySnapshot => {
      let result = [];

      querySnapshot.docs.map(doc => {
        firestore
          .collection("payment-accounts")
          .doc(doc.id)
          .get()
          .then(item => {
            if (item.data().creditAmount > 0) {
              firestore
                .collection("professional-profiles")
                .doc(item.id)
                .get()
                .then(endresult => {
                  result.push({ id: endresult.id, ...endresult.data() }); // executes successful
                });
            }
          });
      });

      res.json({ result }); // the data is outputted before the "querySnapshot.docs.map" is executed...
      // therefore received a blank array (result)
    });
};

以下应该有效(未经测试):

export default (req, res) => {
    firestore
        .collection("category-filters")
        .where(req.query.categoryKey, "==", true)
        .get()
        .then(querySnapshot => {

            const promises = [];
            const paymentAccountsRef = firestore.collection("payment-accounts");

            querySnapshot.docs.map(doc => {
                promises.push(paymentAccountsRef.doc(doc.id).get());
            });

            return Promise.all(promises);

        })
        .then(paymentAccountsSnapshotsArray => {

            const promises = [];
            const professionalProfilesRef = firestore.collection("professional-profiles");

            paymentAccountsSnapshotsArray.forEach(snap => {
                if (snap.data().creditAmount > 0) {
                    promises.push(professionalProfilesRef.doc(snap.id).get());
                }
            });

            return Promise.all(promises);

        })
        .then(professionalProfileSnapshotsArray => {

            const results = [];

            professionalProfileSnapshotsArray.forEach(snap => {
                results.push({ id: snap.id, ...snap.data() });
            });

            res.json({ results });

        })
};

您需要使用 Promise.all() 管理并行文档提取并链接 Promise.all() 返回的不同 Promise,以便仅在所有这些异步操作完成后才发回响应。在您当前的代码中,您将在 那些异步操作完成之前 发回响应。


此外,您可能需要微调此代码以检查不同的快照数组是否为空。这部分由您决定!