How do I sort data by geohash in firestore v9? V8 docs give this example:
const bounds = geofire.geohashQueryBounds(center, radiusInM);
const promises = [];
for (const b of bounds) {
const q = db.collection('cities')
.orderBy('geohash')
.startAt(b[0])
.endAt(b[1]);
promises.push(q.get());
}
// Collect all the query results together into a single list
Promise.all(promises).then((snapshots) => {
const matchingDocs = [];
for (const snap of snapshots) {
for (const doc of snap.docs) {
const lat = doc.get('lat');
const lng = doc.get('lng');
// We have to filter out a few false positives due to GeoHash
// accuracy, but most will match
const distanceInKm = geofire.distanceBetween([lat, lng], center);
const distanceInM = distanceInKm * 1000;
if (distanceInM <= radiusInM) {
matchingDocs.push(doc);
}
}
}
return matchingDocs;
I do not know how to translate it to V9, I have tried like so:
const { latitude, longitude } = location?.coords || {};
if (latitude && longitude) {
const radiusInM = 50 * 100000;
const center = [latitude, longitude];
const bounds = geofire.geohashQueryBounds(center, radiusInM);
for (const b of bounds) {
const q = query(
collection(firestore, "laboratories"),
orderBy("geoHash"),
startAt(b[0]),
endAt(b[1])
);
const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
console.log(doc.id, " => ", doc.data());
});
}
}
But it does not return any results, how does those queries work, because in the bounds results when I set radius to 50 * 100 I get 4 arrays with hashes, I assume those are points on a map
0: (2) ['u3j', 'u3k']
1: (2) ['u3n', 'u3p']
2: (2) ['u3m', 'u3n']
3: (2) ['u3q', 'u3r']
however when I increase the search radius to 50 * 100000 I get only
0: (2) ['h', '~']
I do not understand where do I make mistake, one of those locations is intentionally very close to where I am. And assuming this search was successful, would it return just locations in area or would those be sorted? Perhaps should I use some additional library to for that? Would you recommend one, please? And should I store latitude and longitude together with geohashes or this would be enough?
Posting Frank's comments for visibility.
Your translation to the v9 syntax looks fine, but you have a typo in the field name here: orderBy("geoHash"), should be replaced with orderBy("geohash"), with a lowercase h in hash.
The geohash field is a string value, not a specific data type. You may want to check the article about geohashes or watch a video about it.
To reiterate, the issue in your code here is that you mistyped the field name in your second/v9 query, as you spelled geoHash differently than in the first/v8 query. Even if you remove the startAt/endAt clauses, you'll get no results, as no document has a field with that misspelled name.