Reputation: 4539
I have a firestore object like this :
{
countries:[
country1: {
cities: [
city1: {date_added: timestamp},
...
]
}
...
]
}
So I would like in one query to get a list of cities. I know I could go like (I'm in firestore functions)
const cities = [];
admin.firestore().collection('countries/')
.get()
.then(countriesSnapshot => {
countriesSnapshot .forEach( countryDoc => {
admin.firestore().collection('countries/' + countryDoc.id + '/cities/')
.get()
.then(citySnapshot => {
citySnapshot.forEach( cityDoc => {
cities.push(cityDoc.id);
});
}).catch();
});
}).catch();
But this does a double foreach and I want to process only after everything has resolved. I could with promise.all
but I wonder if there is a simpler way to go - something like
admin.firestore().collection('countries/{countryId}/cities').get().then(citySnapshot ...
Upvotes: 0
Views: 355
Reputation: 4539
So, it looks like there is no possibility to make this happen in a specific subcollection = Frank's answer gave a solution that could work in some cases but won't in mine since my name isn't unique across my DB.
So my solution is to make it happen in two loops anyway but not one into the other - using Promises. Like so :
admin.firestore().collection('countries/')
.get()
.then(countriesSnapshot => {
const citiesPromises = [];
countriesSnapshot.forEach( countryDoc => {
citiesPromises.push(admin.firestore().collection('countries/' + countryDoc.id + '/cities/').get());
});
Promise.all(citiesPromises).then(resources => {
for (const resource of resources) {
resource.forEach( doc => {
// do stuff with doc.id or doc.data()
});
}
}).catch();
}).catch();
Upvotes: 1
Reputation: 598728
If you want to query across all cities
collections, you can use a collection group query:
let cities = db.collectionGroup('cities');
cities.get().then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
console.log(doc.id, ' => ', doc.data());
});
});
This will return all cities across all countries.
Upvotes: 1