Search code examples
firebasegoogle-cloud-firestore

Cannot have inequality filters on multiple properties


I am storing a few places by longitude and latitude on a firestore cloud server.

Now, when the user open a map, I would like to load the item around him, so inside the map bounds.

I make a request to my server

  const ne = map.getBounds()?.getNorthEast();
  const sw = map.getBounds()?.getSouthWest();

  const { data: places } = useApiRequest<Place[]>({
    operation: () =>
      axios.get(
        `/places?${`minLatitude=${sw?.lat()}&maxLatitude=${ne?.lat()}&minLongitude=${sw?.lng()}&maxLongitude=${ne?.lng()}`}`
      ),
  });

And try to query in my BE

    const querySnapshot = await collectionRef
      .where('latitude', '>=', minLatitude)
      .where('latitude', '<=', maxLatitude)
      .where('longitude', '>=', minLongitude)
      .where('longitude', '<=', maxLongitude)
      .get();

This will cause

INVALID_ARGUMENT: Cannot have inequality filters on multiple properties: [latitude, longitude]

Which I now found that is a limitation of firestore (wow)...

My question is, what should I now do ?

Those kinds of filtered query are pretty common for any website with a minimum of filtering. I am pretty surprised by the limitation so I guess there are some workaround or way to do what I need. Am I supposed to query ALL documents and filter on the server ?


Solution

  • Update (April 2024): Firestore recently added the ability to have inequality and range condition on multiple fields in a single query. See the documentation on Query with range and inequality filters on multiple fields and Optimize queries with range and inequality filters on multiple fields for full details.


    Old, outdated answer below 👇

    Firestore currently only supports inequality conditions on a single field. There is no generic workaround for this.

    For this specific use-case, there is a common workaround though, based on pre-calculating geohashes and then filtering on those. For more on this, see the documentation on geoqueries.

    Also see: