I'm trying to figure out a way to get a collection of documents along with their subcollection data.
For example, my tree is...
-locations
-{locationId}
-historic
-april
-airTemp: 12.4
-displayOrder: 4
-august
-airTemp: 14.5
-displayOrder: 9
-december
-airTemp: 13.5
-displayOrder: 12
etc..
...where locationId
is a document and historic
is the subcollection with monthly documents in it.
I know how to get the top level collection items and store it into an array but I want to add their subcollection data (i.e. the jan, feb, etc.) into each document as well.
var locations = []
let ref = db.collection('locations')
db.collection('locations').get()
.then(snapshot => {
snapshot.forEach(doc => {
let location = doc.data()
location.id = doc.id
location.name = doc.name
// get the historic subcollection data here
})
})
How can I get the combined data (collection and subcollection) from each object and then push it into an array?
bounty is wrong structure each month should be its own object
There is no way, with the mobile/web client libraries, to get, in one query, the data of a Firestore document and the data of its sub-collection(s) documents.
There is even no way to get the list of the sub-collections of a document (with the mobile/web client libraries), see https://firebase.google.com/docs/firestore/query-data/get-data#list_subcollections_of_a_document
So you need to know the name of the sub-collections in order to query them, which is your case (name = 'historic').
You could do as follows. First you get all the parent documents and at the same time you use Promise.all()
to query, in parallel, all the 'historic' sub-collections.
var db = firebase.firestore();
var promises = []
db.collection('locations').get()
.then(snapshot => {
snapshot.forEach(doc => {
let location = doc.data()
location.id = doc.id
location.name = doc.data().name
console.log(location);
promises.push(doc.ref.collection('historic').get());
})
return Promise.all(promises);
})
.then(results => {
results.forEach(querySnapshot => {
querySnapshot.forEach(function (doc) {
console.log(doc.id, " => ", doc.data());
});
});
});
Note that the order of the results
array is exactly the same than the order of the promises
array.
Also note that to get the value of a document item (e.g. name
) you need to do doc.data().name
and not doc.name
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With