Home > Mobile >  Lazy loading Google-Maps Markers with firebase
Lazy loading Google-Maps Markers with firebase

Time:10-26

In my app, people can put markers on a map (using google_maps_flutter). These markers are public. When other people open the map, they can see the markers too.

The problem is, this will overtime cause lots of reads, because when you open the map, my app will read every marker from the Firestore database. So I am trying to implement some lazy loading system.

However this has proven to be more difficult than I thought.

This is what I have:

// get all markers within a certain radius
Future<Set<Marker>> getMarkersWithinRadius(LatLng center, double radius) async {
  final Set<Marker> markers = {};

  // only get markers within a certain radius
  final QuerySnapshot<Map<String, dynamic>> querySnapshot = await markersFirestoreReference
      .where('latitude', isGreaterThanOrEqualTo: center.latitude - radius)
      .where('latitude', isLessThanOrEqualTo: center.latitude   radius)
      .where('longitude', isGreaterThanOrEqualTo: center.longitude - radius)
      .where('longitude', isLessThanOrEqualTo: center.longitude   radius)
      .get();

  // loop through all docs and add them to the markers set
  for (final QueryDocumentSnapshot<Map<String, dynamic>> doc in querySnapshot.docs) {
    final MarkerId markerId = MarkerId(doc.data()['markerId']);

    final Marker marker = Marker(
      markerId: markerId,
      position: LatLng(
        doc.data()['latitude'],
        doc.data()['longitude'],
      ),
      infoWindow: InfoWindow(title: markerId.value.toString(), snippet: '*'),
      onTap: () {
        //Navigator.pushNamed(context, '/markerView',
        //    arguments: markerId.value);
      },
    );
    markers.add(marker);
  }
  return markers;
}

This does not work because apparently Firebase doesn't currently support querying multiple fields in a single request.

CodePudding user response:

What you are interested in doing is using a spatial index to query firestore. You would want to store data using geofire. Geofire is a way to deterministically determine an index value for your data and then query upon that index by dividing up the globe into several smaller grids. You can then use geoqueries to query within a certain location and then retrieve realtime updates about that location. This does radius queries from a central location and my recommendation would be that as your map scale changes, update the radius of those queries to be larger than your current mapview. Additionally, while this spatial indexing does work well for knn queries in normal locations, as you move towards the poles, there are issues with adjusting for locations that are closer by traversing the poles.

Extra documents:

GeoFire android documentation

  • Related