In firestore, there are multiple documents that I would like to retrieve. Each document has a unique sourceAddressValue and therefore for the list of N strings, I would like to retrieve potentially N documents.
I tried to do the following:
getLocationAddresses(addresses: string[]) {
const chunkSize = 10;
let addressesChunks = [];
if (addresses.length < chunkSize) {
addressesChunks.push(addresses);
} else {
addressesChunks = [...Array(Math.ceil(addresses.length / chunkSize))].map(_ => addresses.splice(0,chunkSize));
}
console.log(addressesChunks);
return of(...addressesChunks).pipe(
mergeMap<string[], any>((x) => this.db.collection('locations', ref =>
ref.where('sourceLocation', 'array-contains', x)).valueChanges()),
toArray() // when this is removed, the code inside getOrders is triggered multiple times
);
}
public getOrders() {
this.getJSON().subscribe(data => {
this.orders = data.orders;
const addresses = this.orders.map(item => `${item.address}, ${item.postalCode}`);
this.dbService.getLocationAddresses(addresses).subscribe(data => {
console.log('data retrieved');
console.log(data);
});
this.ordersRefreshed.next(this.orders);
});
}
While trying to execute the code above, it seems that the execution is not completed. When I comment out toArray() inside getLocationAddresses, however, the subscribed function is fired multiple times, for each chunk separately.
Does anyone know how to group multiple completions of observable function such that it fires the observer only once?
By using combineLatest, the function getLocationAddresses() returns merged results:
getLocationAddresses(addresses: string[]) {
const chunkSize = 10;
let addressesChunks: string[][] = [];
if (addresses.length < chunkSize) {
addressesChunks.push(addresses);
} else {
addressesChunks = [...Array(Math.ceil(addresses.length / chunkSize))].map(_ => addresses.splice(0,chunkSize));
}
console.log(addressesChunks);
const observables = addressesChunks.map(addresses => this.db.collection('locations', ref =>
ref.where('sourceLocation', 'in', addresses)).valueChanges());
return combineLatest(observables)
.pipe(map(arr => arr.reduce((acc, cur) => acc.concat(cur) ) ),);
}