Javascript Firebase firestore&;Express-buildjson获取嵌套文档

Javascript Firebase firestore&;Express-buildjson获取嵌套文档,javascript,firebase,express,google-cloud-firestore,google-cloud-functions,Javascript,Firebase,Express,Google Cloud Firestore,Google Cloud Functions,到目前为止,我正在使用express和firebase云功能构建一个应用程序。我无法根据此db创建嵌套json: 代码如下: exports.tstMenu = (req, res) => { let shop = db.collection('shops').doc(req.params.name).collection('menus'); shop.get() .then((data) => { let menu = [];

到目前为止,我正在使用express和firebase云功能构建一个应用程序。我无法根据此db创建嵌套json:

代码如下:

exports.tstMenu = (req, res) => {
    let shop = db.collection('shops').doc(req.params.name).collection('menus');
    shop.get()
    .then((data) => {
        let menu = [];
        data.forEach((doc) => {
            let categories = getCategories(doc.id, shop);
            menu.push({
                menuID: doc.id,
                name: doc.data().name,
                position: doc.data().position,
                categories: categories,
            });
            console.log(menu);
        });
        return res.json(menu);
    })
    .catch((err) => {
        console.error(err);
        return res.status(500).json({ error: err.message});
    });
}

function getCategories(id, db){
    let shop = db.doc(id).collection('categories');
    return shop.get()
    .then((data) => {
        let categs = [];
        data.forEach((doc) => {
            var menuElements = [];//getMenuElement(doc.id, shop);
            categs.push({
                catID: doc.id,
                name: doc.data().name,
                position: doc.data().position,
                menuElements: menuElements,
            });
        });
        return categs;
    });
}
tstMenu
的结果是:

当日志显示以下内容时:


有人能告诉我怎么修吗?我很确定,当
tstMenu
到达
return res.json(菜单)时,不会收到承诺

您的问题在这一行中:

let categories = getCategories(doc.id, shop);
getCategories
是一种异步方法。它会返回一个承诺,因此您不能直接使用它

您可以在
然后
回调中完成分配,也可以使用
异步等待

exports.tstMenu = (req, res) => {
    let shop = db.collection('shops').doc(req.params.name).collection('menus');
    shop.get()
    .then((data) => {
     let menu = [];
     const promises = data.docs.map((doc) =>  // change this from forEach to map
            getCategories(doc.id, shop).then(categories =>{
               menu.push({
                menuID: doc.id,
                name: doc.data().name,
                position: doc.data().position,
                categories: categories,
            });
        );

     return Promise.all(promises).then(()=> res.json(menu)); // return res after all promises completed
       
    })
    .catch((err) => {
        console.error(err);
        return res.status(500).json({ error: err.message});
    });
}


谢谢您的快速回答,我已经尝试过了,但是现在什么都没有显示,而且
控制台.log(菜单)
内部
然后(类别)
显示4个空数组
[]
即使使用第三个函数也可以这样做吗?包括第三次呼叫并承诺获取菜单元素数据?@Dennis如果您跟踪返回的
promise
应该等待的内容,您可以链接任意数量的呼叫。如果您要在
forEach
块中调用
getMenuElements
函数,您还需要像上面那样修改
getCategories
方法。刚刚尝试过,出现了以下错误:
>C:\WINDOWS\system32\cmd.exe-firebase-service[260196]:C:\ws\src\node\u http2.cc:893:Assertion(flags\SESSION\u STATE\u READING\u STOPPED)!=(0)“失败”。>1:002006CE节点::MakeCallback+3982
让我们来看看。
exports.tstMenu = async (req, res) => {
  try {
    let shop = db.collection('shops').doc(req.params.name).collection('menus');
    const data = await shop.get()
    let menu = [];
     const promises = data.docs.map((doc) =>  // change this from forEach to map
            getCategories(doc.id, shop).then(categories =>{
               menu.push({
                menuID: doc.id,
                name: doc.data().name,
                position: doc.data().position,
                categories: categories,
            });
        );

    await  Promise.all(promises);
    return res.json(menu)
  } catch(err) { 
      console.error(err);
      return res.status(500).json({ error: err.message});
    }
}