首页 > 解决方案 > How to Retrieve location from Firestore and display on Google Map flutter

问题描述

Following these two tutorials :

Flutter Google Maps Firestore Geolocation

Flutter Retrieve Markers From Firestore

I Integrated Map feature inside my app. which locate the current user position.

My issue is I would like to retrieve other users position from firestore and display them on the map as well.

(or in this case it's not users but restaurants offer)

but it's not showing on the map, any ideas what I'm I doing wrong ?

Here is my collection Screenshot

And here is Complete working Code

class _MapScreenState extends State<MapScreen> {
  StreamSubscription _locationSubscription;
   Location _locationTracker = Location();
   Marker marker;
   Circle circle;
   GoogleMapController _controller;

   String location;
   RxList mapList = <OffersModel>[].obs;
   var isLoading = true.obs;

  final allOfferCollection = FirebaseFirestore.instance.collection('all-offers');

   Map<MarkerId, Marker> markers = <MarkerId, Marker>{
   };

   void initState() {
    getMarkerData();
    super.initState();
   }

   void initOffer(specify, specifyId) async
   {
    var p=specify['location'];
    var markerIdVal = specifyId;
    final MarkerId markerId = MarkerId(markerIdVal);
    final Marker marker = Marker(
      markerId: markerId,
      position: LatLng(p['location'].latitude, p['location'].longitutde),
      infoWindow: InfoWindow(title: specify['name'], snippet: specify['location'])
    );
    setState(() {
      markers[markerId] = marker;
    });
   }

   Future<DocumentReference> getMarkerData() async {
    try {
      allOfferCollection.get().then((snapshot) {
      print(snapshot);
      if(snapshot.docs.isNotEmpty){
        for(int i= 0; i < snapshot.docs.length; i++)
          {
            initOffer(snapshot.docs[i].data, snapshot.docs[i].id);
          }
      }
      snapshot.docs
          .where((element) => element["location"] == location)
          .forEach((element) {
        if (element.exists) {
          mapList.add(OffersModel.fromJson(element.data(), element.id));
        }
      });
    });
  } finally {
  isLoading(false);
  }
  }

  static final CameraPosition initialLocation = CameraPosition(
    target: LatLng(36.723062, 3.087800),
    zoom: 14.4746,
    // zoom: 14,

  );

  Future<Uint8List> getMarker() async {
    ByteData byteData = await DefaultAssetBundle.of(context).load("assets/marker.png");
    return byteData.buffer.asUint8List();
  }

  void updateMarkerAndCircle(LocationData newLocalData, Uint8List imageData) {
    LatLng latlng = LatLng(newLocalData.latitude, newLocalData.longitude);
    this.setState(() {
      marker = Marker(
          markerId: MarkerId("home"),
          position: latlng,
          rotation: newLocalData.heading,
          draggable: false,
          zIndex: 2,
          flat: true,
          anchor: Offset(0.5, 0.5),
          icon: BitmapDescriptor.fromBytes(imageData));

    });
  }

  void getCurrentLocation() async {
    try {

      Uint8List imageData = await getMarker();
      var location = await _locationTracker.getLocation();

      updateMarkerAndCircle(location, imageData);

      if (_locationSubscription != null) {
        _locationSubscription.cancel();
      }

      _locationSubscription = _locationTracker.onLocationChanged.listen((newLocalData) {
        if (_controller != null) {
          _controller.animateCamera(CameraUpdate.newCameraPosition(new CameraPosition(
              bearing: 192.8334901395799,
              target: LatLng(newLocalData.latitude, newLocalData.longitude),
              tilt: 0,
              zoom: 18.00
          )));
          updateMarkerAndCircle(newLocalData, imageData);
        }
      });

    } on PlatformException catch (e) {
      if (e.code == 'PERMISSION_DENIED') {
        debugPrint("Permission Denied");
      }
    }
  }

  @override
  void dispose() {
    if (_locationSubscription != null) {
      _locationSubscription.cancel();
    }
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: GoogleMap(
          mapType: MapType.normal,
          initialCameraPosition: initialLocation,
          markers: Set.of((marker != null) ? [marker] : []),
          // circles: Set.of((circle != null) ? [circle] : []),
          onMapCreated: (GoogleMapController controller) {
            setState(() {
              _controller = controller;
            });
          },
          myLocationEnabled: true,
          compassEnabled: true,

        ),
      ),
    );
    }
  }

Edit : Here is my logcat issue

    E/flutter (20815): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: NoSuchMethodError: Closure call with mismatched arguments: function '[]'
E/flutter (20815): Receiver: Closure: () => Map<String, dynamic> from Function 'data':.
E/flutter (20815): Tried calling: []("location")
E/flutter (20815): Found: []() => Map<String, dynamic>
E/flutter (20815): #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
E/flutter (20815): #1      _MapScreenState.initOffer (package:fayda/dev/MapScreen/MapScreen.dart:46:18)
E/flutter (20815): #2      _MapScreenState.getMarkerData.<anonymous closure> (package:fayda/dev/MapScreen/MapScreen.dart:70:13)
E/flutter (20815): #3      _rootRunUnary (dart:async/zone.dart:1362:47)
E/flutter (20815): #4      _CustomZone.runUnary (dart:async/zone.dart:1265:19)
E/flutter (20815): <asynchronous suspension>
E/flutter (20815): 
I/chatty  (20815): uid=10168(com.app.fayda) 1.ui identical 2 lines
E/flutter (20815): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: NoSuchMethodError: Closure call with mismatched arguments: function '[]'
E/flutter (20815): Receiver: Closure: () => Map<String, dynamic> from Function 'data':.
E/flutter (20815): Tried calling: []("location")
E/flutter (20815): Found: []() => Map<String, dynamic>

标签: firebasefluttergoogle-mapsgoogle-cloud-firestorelocation

解决方案


我添加了地理编码器

 Future<DocumentReference> getMarkerData() async {
LatLng pos;
String id, name, loc;
try {
  allOfferCollection.get().then((snapshot) async {
    if (snapshot.docs.isNotEmpty) {
      for (int i = 0; i < snapshot.docs.length; i++) {
        Map<dynamic, dynamic> map = snapshot.docs[i].data();

        id = map['name'];
        name = map['categoryId'];
        loc = map['location'];
        var addresses = await Geocoder.local.findAddressesFromQuery(loc);
        var first = addresses.first;
        pos = new LatLng(
            first.coordinates.latitude, first.coordinates.longitude);
        initOffer(pos, id, name);
      }
    }
  });
} finally {
  isLoading(false);
}
}

推荐阅读