5

I am building a food ordering app like Uber eats. So, I am using flutter to make an app, however now I ran into a problem of finding the nearest restaurants.

I am currently storing location details using geoflutterfire package. Please see the picture attached. enter image description here

Have a look into my code.

getLocation() async {
// Create a geoFirePoint

  GeoFirePoint center =
      geo.point(latitude: 28.706707247639613, longitude: 80.58572410373661);

// get the collection reference or query
  var collectionReference = _firestore.collection('locations');

  double radius = 5;
  String field = 'position';

  Stream<List<DocumentSnapshot>> stream = geo
      .collection(collectionRef: collectionReference)
      .within(center: center, radius: radius, field: field);

  stream.forEach((element) {
    element.forEach((e) {
      double fbLat = e.get('position')['geopoint'].latitude;
      double fbLng = e.get('position')['geopoint'].longitude;

      LatLng loc2 = LatLng(fbLat, fbLng);
      LatLng loc1 = LatLng(center.latitude, center.longitude);

      final distance =
          distanceBetweenTwoLocations(location1: loc1, location2: loc2);
      print('=======distance is ======');
      print('${distance / 1000}KM');
     
    });
  });
}

Yes, I am getting back nearest places from from database, however I am getting back 30+ results, out of which only 6-7 are correct, and I think it is not efficient to scale because it is increasing my reads as well as overhead at client side to filter them.

Now my question is, how do I implement a perfect geoqueries to filter nearest restaurants and drivers in cloud firestore? Please help.

badmasW
  • 121
  • 7

1 Answers1

3

Most geoquery implementations for Firestore (like the one documented by Firebase itself) use geohash values to allow a range query on two values (lat/lon). While geohash values allow the geoquery to function, they are by definition imprecise, and they match items in a rectangular area.

When you look for documents in the green area, the range of geohashes may actually extend to include the red area:

enter image description here

To limit the returned items to the circular radius you want, you need to post-process the results as you're doing. In my testing the queries read about 5x more documents than needed, with some queries (typically the ones with even fewer results) reading up to 15x more. Based on that, your results seem to be about average.

If you're interesting in learning more, I recommend checking out the video of a talk I did a few years ago: Querying Firebase and Firestore based on geographic location or distance.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • 1
    Thanks a lot for your detailed explanation. I agree with you and watched the entire video as well. Just one more question, Is there any way to limit the data so that I can implement pagination. – badmasW Nov 05 '21 at 00:17
  • While you can certainly add a limit to the query, it depends on the library you use. The link to the document shows a place where it's easy to add such a condition. But it likely won't do what you want, as the results won't be sorted by distance and you'll be paginating documents that you may cull later (the ones in the red area). – Frank van Puffelen Nov 05 '21 at 00:27