| name | mobile-maps-location |
|---|---|
| description | Add maps and geolocation to a React Native/Expo or Flutter app. Covers react-native-maps, google_maps_flutter, expo-location, geofencing, background location tracking, marker clustering, and permission flows. Use when the user wants to display a map, track user location, or build location-aware features. |
| standards-version | 1.6.3 |
Use this skill when the user:
- Wants to show a map with markers, routes, or polygons
- Needs to get the user's current location
- Asks about react-native-maps, google_maps_flutter, or expo-location
- Mentions "map", "geolocation", "GPS", "geofencing", "directions", "coordinates", or "location tracking"
- Wants background location tracking or location-based notifications
- Framework: Expo (React Native) or Flutter
- Map provider: Google Maps (default, cross-platform) or Apple Maps (iOS only)
- Features needed: static map, interactive markers, user location, geofencing, or background tracking
-
Install map dependencies (Expo). Use react-native-maps:
npx expo install react-native-maps
Add the config plugin in
app.json:{ "expo": { "plugins": [ ["react-native-maps", { "googleMapsApiKey": "YOUR_GOOGLE_MAPS_API_KEY" }] ] } }Get an API key from Google Cloud Console with the Maps SDK for Android and iOS enabled.
-
Install map dependencies (Flutter).
flutter pub add google_maps_flutter
Add the API key to
android/app/src/main/AndroidManifest.xml:<meta-data android:name="com.google.android.geo.API_KEY" android:value="YOUR_GOOGLE_MAPS_API_KEY"/>
And
ios/Runner/AppDelegate.swift:GMSServices.provideAPIKey("YOUR_GOOGLE_MAPS_API_KEY")
-
Display a basic map with markers (Expo).
import MapView, { Marker } from "react-native-maps"; export default function MapScreen() { return ( <MapView style={{ flex: 1 }} initialRegion={{ latitude: 37.7749, longitude: -122.4194, latitudeDelta: 0.0922, longitudeDelta: 0.0421, }} showsUserLocation > <Marker coordinate={{ latitude: 37.7749, longitude: -122.4194 }} title="San Francisco" description="Bay Area" /> </MapView> ); }
-
Get user location (Expo). Install expo-location:
npx expo install expo-location
Request permission and get coordinates:
import * as Location from "expo-location"; async function getCurrentLocation() { const { status } = await Location.requestForegroundPermissionsAsync(); if (status !== "granted") { throw new Error("Location permission denied"); } const location = await Location.getCurrentPositionAsync({ accuracy: Location.Accuracy.High, }); return { latitude: location.coords.latitude, longitude: location.coords.longitude, }; }
-
Background location tracking. For Expo, add the background location task:
import * as TaskManager from "expo-task-manager"; import * as Location from "expo-location"; const LOCATION_TASK = "background-location-task"; TaskManager.defineTask(LOCATION_TASK, ({ data, error }) => { if (error) return; const { locations } = data as { locations: Location.LocationObject[] }; // Send locations to your API }); async function startBackgroundTracking() { const { status } = await Location.requestBackgroundPermissionsAsync(); if (status !== "granted") return; await Location.startLocationUpdatesAsync(LOCATION_TASK, { accuracy: Location.Accuracy.Balanced, distanceInterval: 100, showsBackgroundLocationIndicator: true, }); }
-
Geofencing. Trigger actions when the user enters or exits a region:
import * as Location from "expo-location"; const geofences = [ { identifier: "office", latitude: 37.7749, longitude: -122.4194, radius: 100, notifyOnEnter: true, notifyOnExit: true, }, ]; await Location.startGeofencingAsync("geofence-task", geofences);
-
Flutter location with geolocator.
flutter pub add geolocator
import 'package:geolocator/geolocator.dart'; Future<Position> getCurrentPosition() async { final permission = await Geolocator.checkPermission(); if (permission == LocationPermission.denied) { await Geolocator.requestPermission(); } return Geolocator.getCurrentPosition( locationSettings: const LocationSettings( accuracy: LocationAccuracy.high, ), ); }
User: "Show a map with the user's location and let them drop pins."
Agent:
- Installs react-native-maps and expo-location with
mobile_installDependency - Generates a map screen with
mobile_addMap - Adds the Google Maps config plugin to app.json with API key placeholder
- Adds location permission with
mobile_addPermission - Implements
getCurrentLocation()to center the map on the user - Adds an
onLongPresshandler to drop markers at the tapped coordinate - Stores markers in state with title, coordinate, and timestamp
- Reminds user to get a Google Maps API key and use a dev build
| Step | MCP Tool | Description |
|---|---|---|
| Generate map screen | mobile_addMap |
Scaffold map component with provider config and markers |
| Add location permission | mobile_addPermission |
Add location permission to app.json |
| Install packages | mobile_installDependency |
Install react-native-maps, expo-location |
| Verify build | mobile_checkBuildHealth |
Ensure native map module compiles |
- Missing API key - Google Maps renders a blank gray view without a valid API key. Get one from Google Cloud Console and enable the Maps SDK.
- Expo Go incompatibility - react-native-maps requires a dev build. It does not work in Expo Go.
- Background location battery drain - High-accuracy background tracking drains the battery fast. Use
Accuracy.Balancedand a reasonabledistanceInterval. - Location permission UX - Request location only when the user needs it (not on app launch). Explain why in the permission rationale string.
- Android emulator location - The Android emulator has no GPS by default. Set a mock location in Extended Controls > Location.
- Map renders behind other views - On Android,
MapViewuses a native surface that renders above React Native views. UseMarkercallouts instead of overlaying custom components.
- Mobile Permissions - location permission request patterns
- Mobile Deep Links - deep link to a map location in the app
- Mobile Push Notifications - location-triggered notifications