0

I have a collection of Firebase locations with lat and long fields. Once a button is pressed in my flutter Android app, it will measure the distance between the user and the different locations and will be displayed in the UI. Below is the code for the Streambuilder.

StreamBuilder(
    stream: FirebaseFirestore.instance.collection("New Shop").snapshots(),
    builder: (context, snapshot) {
      if (snapshot.hasData) {
        final List<LatLng> latLen = <LatLng>[];
        for (int i = 0; i < snapshot.data!.docs.length; i++) {
          latLen.add(LatLng(snapshot.data!.docs[i].get('lat'),
              snapshot.data!.docs[i].get('long')));
        }

        loadData() async {
          for (int i = 0; i < snapshot.data!.docs.length; i++) {
            markers.add(Marker(
              markerId: MarkerId(i.toString()),
              position: latLen[i],
              infoWindow: InfoWindow(
                title: snapshot.data!.docs[i].get('name'),
              ),
            ));
          }
        }

        loadData();

Below is the code to update user current location.

  Future<Position> _determinePosition() async {
bool serviceEnabled;
LocationPermission permission;

serviceEnabled = await Geolocator.isLocationServiceEnabled();

if (!serviceEnabled) {
  return Future.error('Location services are disabled');
}

permission = await Geolocator.checkPermission();

if (permission == LocationPermission.denied) {
  permission = await Geolocator.requestPermission();

  if (permission == LocationPermission.denied) {
    return Future.error("Location permission denied");
  }
}

if (permission == LocationPermission.deniedForever) {
  return Future.error('Location permissions are permanently denied');
}

Position position = await Geolocator.getCurrentPosition(
    desiredAccuracy: LocationAccuracy.high);

userLatLng = LatLng(position.latitude, position.longitude);

return position;

}

Below is the code to display the distance.

                              Expanded(
                            child: ListTile(
                              horizontalTitleGap: 10,
                              title: Text(
                                shop['name'],
                                maxLines: 1,
                              ),
                              subtitle: Text(
                                "${calculateDistance(userLatLng.latitude, userLatLng.longitude, shop['lat'].toDouble(), shop['long'].toDouble()).toStringAsFixed(2)}km from you\n${shop['address']}",
                                maxLines: 2,
                              ),
                              isThreeLine: true,
                              contentPadding: const EdgeInsets.all(0),
                            ),
                          ),

I would like to sort the locations by the distance of the current user, however I cannot use orderBy as there is no distance field in the documents and the sorted list is unique to every user due to their different locations.

taro
  • 11
  • 2
  • Are you asking [how to calculate the distance between two lat/lon points](https://www.google.com/search?q=how+to+calculate+the+distance+between+two+lat%2Flon+points)? – Frank van Puffelen Jul 24 '23 at 13:42
  • Nope I have a button which calculates the distance between the user and the different locations. However I have trouble sorting the documents by this calculated distance and displaying it on the UI. I cant use orderBy as each user will have a unique current location. – taro Jul 24 '23 at 13:51

2 Answers2

0

For this you can use Distance matrix API

Akshay Gupta
  • 384
  • 1
  • 8
0

You can use the GeoFlutterFire library:

GeoFlutterFire is an open-source library that allows you to store and query a set of keys based on their geographic location...

GeoFlutterFire stores data in its own format within your Firestore database. This allows your existing data format and Security Rules to remain unchanged while still providing you with an easy solution for geo queries."

Note that with the current version you cannot use orderBy() (See "Limitations" section at the end of the doc), but you can sort the results in the frontend.

Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121
  • Sorry I am not very sure what you mean by sorting the results in the frontend. Do you mean creating a function to sort 'snapshot.data!.docs'. – taro Jul 24 '23 at 13:35
  • Hey @taro, see https://stackoverflow.com/a/63547600/3371862 – Renaud Tarnec Jul 24 '23 at 13:58
  • Hello @taro, did you have the time to look at the other SO answer? Do you need more help? – Renaud Tarnec Jul 26 '23 at 07:33
  • It's alright I referred to https://stackoverflow.com/questions/60805917/how-to-sort-list-of-locations-in-flutter-from-firestore/64966888#64966888 as I couldn't run geoflutterfire. But I appreciate your help very much thank you for spending time out of your day to reply to my queries. – taro Jul 26 '23 at 11:52