To put a map in a Flutter app, use google_maps_flutter with a GoogleMap widget and an API key from Google Maps Platform. To find where the user is, use geolocator: check that location services are on, check or request permission, then call Geolocator.getCurrentPosition().

This guide is for Flutter developers building a "find near me" screen. It uses google_maps_flutter 2.19.0 (publisher flutter.dev) and geolocator 14.1.2 (publisher baseflow.com), as of October 2026. The running example shows nearby bakeries on a map.

In short:

  • google_maps_flutter supports Android, iOS and web. geolocator also covers desktop.
  • Enable a separate Google Maps SDK for each platform you ship.
  • Android 12 and newer lets users grant only approximate location.
  • Ask for location when the user taps "Near me", not at launch.

Get a key and enable one SDK per platform

The package readme lists the steps. Get an API key from Google Maps Platform, then enable "Maps SDK for Android" for Android, "Maps SDK for iOS" for iOS, and "Maps JavaScript API" for web. Each platform also has its own setup page for where the key goes.

Use separate, API-restricted keys for each platform: restrict the Android key by package name and signing-certificate SHA-1 fingerprint, the iOS key by bundle identifier, and the web key by HTTP referrer. Maps Platform bills per use, with a free monthly allowance per product. Check the Maps Platform pricing page before launch.

A map and a pin

GoogleMap(
                initialCameraPosition: const CameraPosition(
                  target: LatLng(37.4220, -122.0841), zoom: 14),
                markers: {
                  const Marker(markerId: MarkerId('b1'),
                      position: LatLng(37.4230, -122.0830),
                      infoWindow: InfoWindow(title: 'Sourdough & Co')),
                },
                myLocationEnabled: true,
              )
              

initialCameraPosition sets where the map opens, and markers is a set of pins. Keep the GoogleMapController from onMapCreated if you want to move the camera later.

For custom pins, the readme describes Advanced Markers, which need a Map ID. On iOS a custom PinConfig may not show, so the readme suggests a bitmap there.

Android and iOS permissions differ

For geolocator, add these to AndroidManifest.xml: ACCESS_COARSE_LOCATION, and ACCESS_FINE_LOCATION if you need precision. The readme says that since Android 12 users can grant only approximate location even if you ask for fine, so request both together. On iOS, add NSLocationWhenInUseUsageDescription with a real reason to Info.plist.

Background tracking is a heavier path. It adds ACCESS_BACKGROUND_LOCATION on Android and Background Modes on iOS, and the readme warns you will have to explain it to Apple. If you only need the position while the screen is open, do not add it.

The permission flow that does not crash

The readme's recommended sequence has four steps:

  1. Call Geolocator.isLocationServiceEnabled(). If false, tell the user to turn location on.
  2. Call checkPermission(). If it is denied, call requestPermission().
  3. If the result is deniedForever, stop and show a button that opens settings.
  4. Call getCurrentPosition() only if location services are enabled and permission is whileInUse or always; otherwise stop and explain the unavailable or denied state. Wrap position acquisition in try/catch and show a recoverable error if it fails.
final pos = await Geolocator.getCurrentPosition(
                locationSettings: const LocationSettings(accuracy: LocationAccuracy.high),
              );
              

To follow the user, use getPositionStream with a distanceFilter in meters so you do not get an update for every step. getLastKnownPosition() is instant but can be null or old.

Ask at the moment of need

Show a short sentence first: "We use your location only to show bakeries near you." Then trigger the system prompt from the "Near me" button. A denied prompt on iOS cannot be shown again. The user must go to Settings. That is why deniedForever needs its own screen.

Privacy forms must mention location

Both stores ask what data your app collects. Location is one of them. Update your privacy policy and store data-safety form when you add either package, and describe the purpose in plain words.

GrowApps lists location in its data-safety checklist

GrowApps keeps a data-safety checklist that maps each package to the data it collects, for answering Google Play's Data safety form. It has entries for both geolocator and google_maps_flutter, listing approximate location as optional data used for app functionality. It does not set up your Maps key. More at growapps.ai.

Deny location permission twice

Run the four-step flow on a real phone. Deny permission once, deny it twice, then allow it. Each path should show a clear message, never an exception.

Sources and further reading