Firebase Firestore从集合文档中获取数据,然后从一个数组中获取子集合文档

时间:2020-05-01 01:11:37

标签: node.js firebase express promise google-cloud-firestore

我正在将节点服务器与express配合使用,并尝试从firestore数据库中获取数据。我的数据库结构如下

-Resource Collection
  - Documents with fields
     - comments subcollection
         - documents with fields
     - subresource subcollection
         - documents with fields

我正在尝试将上述所有数据映射到单个数组中,并将子资源和注释嵌套在单个数组中。以下是我的代码。日志在一个数组中具有正确的数据,但是当我发回响应时,它仅显示1个资源,并且每次都是随机的。不应该promise.all然后所有数据收集完毕后阻止执行吗?我什至正确使用了诺言吗?

    response.set('Cache-Control','public, max-age=300, s-maxage=600');
    db.collection('Resources').get()
    .then(snapshot => {
        let Resources = snapshot.docs.map(doc => {
            var promises = [];
            let documentData = doc.data();
            documentData['id'] = doc.id;
            promises.push(db.collection('Resources').doc(documentData.id).collection('SubResources').get()
            .then(snapshot => {
                documentData['subresources'] = snapshot.docs.map(doc => {
                    let subResourceData = doc.data();
                    subResourceData['id'] = doc.id;
                    return subResourceData;   
                })
            }));
            promises.push(db.collection('Resources').doc(documentData.id).collection('Comments').get()
            .then(snapshot => {
                documentData['comments'] = snapshot.docs.map(doc => {
                    return doc.data();  
                })
            }));
            Promise.all(promises).then(function(){
                console.log(documentData);
                return response.json(documentData);            
            })
        })        

    })
    .catch(err => {
        console.log('Error getting documents', err);
    });
});

1 个答案:

答案 0 :(得分:0)

您的Promise.all()仅兑现了获取子资源和注释的承诺,而不是“资源”本身的承诺。因此对于无论哪种资源,它都可以先完成获取子资源和注释的操作,然后解析并返回数据。

下面是对代码的略微修改,以便它等待所有资源完成提取注释/子资源,然后将它们作为数组返回。

response.set('Cache-Control','public, max-age=300, s-maxage=600');

db.collection('Resources').get()
.then(snapshot => {
    let ResourcePromises = snapshot.docs.map(doc => {
        var promises = [];
        let documentData = doc.data();
        documentData['id'] = doc.id;
        promises.push(db.collection('Resources').doc(documentData.id).collection('SubResources').get()
        .then(snapshot => {
            documentData['subresources'] = snapshot.docs.map(doc => {
                let subResourceData = doc.data();
                subResourceData['id'] = doc.id;
                return subResourceData;   
            })
        }));
        promises.push(db.collection('Resources').doc(documentData.id).collection('Comments').get()
        .then(snapshot => {
            documentData['comments'] = snapshot.docs.map(doc => {
                return doc.data();  
            })
        }));
        return Promise.all(promises).then(function(){
            //console.log(documentData);
            //return response.json(documentData);            
            return documentData;
        })
    });

    Promise.all(ResourcePromises).then(function(allResources) {
        return response.json(allResources);
    })

})
.catch(err => {
    console.log('Error getting documents', err);
});

您可能希望将代码重构为单独的函数,以使其更具可读性。