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: