I am trying to combine Geofirestore with "Compound (AND) queries".
The original code example (from documentation https://firebase.google.com/docs/firestore/solutions/geoqueries#web-modular-api)
const bounds = geofire.geohashQueryBounds(center, radiusInM);
const promises = [];
for (const b of bounds) {
const q = query(
collection(db, 'cities'),
orderBy('geohash'),
startAt(b[0]),
endAt(b[1]));
promises.push(getDocs(q));
}
// Collect all the query results together into a single list
const snapshots = await Promise.all(promises);
Say I also want to query documents within a specific date range e.g. birthday, changing the query to:
const bounds = geofire.geohashQueryBounds(center, radiusInM);
const promises = [];
for (const b of bounds) {
const q = query(
'myCollection',
orderBy('birthday'),
where('birthday', '<=', maxDate),
where('birthday', '>=', minDate),
orderBy('geohash'),
startAt(b[0]),
endAt(b[1])
);
promises.push(getDocs(q));
}
// Collect all the query results together into a single list
const snapshots = await Promise.all(promises);
With the original code Firestore returns the expected test document, but if I add birthday as query params Firestore returns 0 documents. I seem to be unable to understand why that is. Does anyone have an insight on this? Any help is appreciated.
BTW! If the query is only on birthday, the expected test document is returned
From the documentation on Firestore query limitations:
In a compound query, range (<, <=, >, >=) and not equals (!=, not-in) comparisons must all filter on the same field.
Combining that with knowledge the startAt
and endAt
are just another way to write >
and <
conditions, and it becomes clear that there's no way to filter both by geohash range and birthday
range in a single query.
If you store birthDate
in a format that supports equality checks and the range of dates is small enough, you may be able to use an in
condition for it. For example, say you care about birth year you'd store it as a separate field, you could do:
where('birthyear', 'in', [1970, 1971, 1972])
To learn more about why this sort of query currently isn't possible on Firestore, I recommend watching my talk from some years ago: Querying Firestore based on geographic location or distance.
Also check out the questions to some previous answers on the topic: