Skip to content
Advertisement

The best way to query by location in firestore

I am using Firebase 8.10.0 with Vue js 2.6.14

I am trying to query in Firestore about the documents that are less than 3 km away from my location And discovered that I could not do this query in firestore, I was frankly disappointed Then after watching a video by Frank van Puffelen on YouTube “Querying Firebase and Firestore”1 I understood that the best way to do this query is through Geohash So now I’m using ngeohash to convert lat long to geohash code then geofirestore to query ( i am not using geofirestore to add the data to firestore because i don’t find a way to add doc with specific id or update an existing doc with geofirestore )

convert lat long to geohash code

import geohash from "ngeohash";

const ask = async () => {
  try {
    const loc = await new Promise((resolve, reject) => {
      navigator.geolocation.getCurrentPosition(resolve, reject, {
        enableHighAccuracy: true,
      });
    });
    const { latitude, longitude, accuracy } = loc.coords;

    return {
      lat: latitude,
      lng: longitude,
      accuracy: accuracy,
      geohash: geohash.encode(latitude, longitude)
    };
  } catch (err) {
    console.log(err);
  }
};

add data to firestore

ref.set({
  g: {
    geopoint: new db.GeoPoint(lat, lng),
    geohash: geohash
  },
  ...data
}, { merge: true }).then(() => {
  console.log("Done");
});

query from firestore

let query = geocollection.near({ center: new db.GeoPoint(lat, lng), radius: 3 });
query.get().then((data) => {
  console.log(data.size);
});

Is what I’m doing right is this the best way to query by location in firestore? and does geofirestore increase the number of readings because I made a query a while ago and the result was only 5 from 1000 documents, but I found that more than 60 readings were recorded in the Firebase console. Is this normal or was it only supposed to be 5 readings?

Answer

Geohashes allow you to query documents within a certain geographic areas. These areas may overlap with the distance from a specific point that you specify, but you will usually need to query multiple ranges of geohashes to get all documents around a certain point.

A simple visualization of this based on what I showed in the video you linked:

enter image description here

So the query here is to return all documents within the gray circle. But in order to get those documents, we need to query all four colored ranges of geohashes.

If you have a relatively uniform distribution of the documents, you might end up with this:

enter image description here

Each pin in this image is a document that is read by Firestore, but only the green pins are documents that fall within the range you actually wanted.

In my experiments, for a uniform distribution of documents, you end up reading between 2x and 10x more documents than needed with this approach. If this overreading is a cost concern for you, consider using the Realtime Database and its geofire library for your geoqueries. While the overreading will be the same, the billing structure is based on bandwidth and the amount of bandwidth consumed by the geoindex is pretty minimal there.

Advertisement