Firebase Firestore получает данные из документов коллекций, а затем из документов коллекций в одном массиве. - PullRequest
0 голосов
/ 01 мая 2020

Я использую сервер узлов с express и пытаюсь получить данные из базы данных firestore. Моя структура базы данных выглядит следующим образом:

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

Я пытаюсь отобразить все вышеперечисленные данные в один массив с вложенным ресурсом, а комментарии - это вложенный массив внутри одного массива. Ниже приведен мой код. Журнал содержит правильные данные в одном массиве, но когда я отправляю ответ, он показывает только 1 ресурс, и это тоже каждый раз случайно. Не следует ли обещать. Затем блокировать выполнение после того, как все данные были собраны? Я даже правильно использую обещания?

    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 голосов
/ 01 мая 2020

Ваш 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);
});

Вы можете реорганизовать код для разделения функций, чтобы они были более читабельными.

...