@react-native-community/geolocation

repository·master·Indexed 23 days ago

https://github.com/michalchudziak/react-native-geolocation

A Geolocation API module for React Native (version 3.3.0) that extends the Web Geolocation specification. It supports TurboModules, legacy architecture, and the modern Android Play Services Location API for iOS and Android. The library provides methods to retrieve the current position via getCurrentPosition(), track location changes with watchPosition(), and manage permissions using requestAuthorization().

Tokens
2.4K
Snippets
6
Records
18
Agent score
81%

What's inside @react-native-community/geolocation

  1. Migrate from core react-native Geolocation to @react-native-community/geolocation

    master

    Since Geolocation was split out of the React Native core, you must transition from using the global navigator.geolocation to importing the module explicitly.

    Step 1: Update Configuration Calls Change:

    navigator.geolocation.setRNConfiguration(config);

    to:

    import Geolocation from '@react-native-community/geolocation';
    
    Geolocation.setRNConfiguration(config);

    Step 2: (Optional) Maintain Browser Compatibility If you want to keep the API aligned with the browser (for cross-platform apps) or support backward compatibility, add this to the root of your app (e.g., App.js):

    navigator.geolocation = require('@react-native-community/geolocation');
    import Geolocation from '@react-native-community/geolocation';
    
    Geolocation.setRNConfiguration(config);
  2. Configure Android permissions for Geolocation

    master

    To request access to location on Android, add one of the following lines to your AndroidManifest.xml:

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    or

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

    Important Requirements:

    • Runtime Permissions: For Android API >= 23, you must manually check for and request ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION using the PermissionsAndroid API. Failure to do so may cause a hard crash.
    • Mocked Positions: On Android API >= 18, position objects include a mocked boolean indicating if the position was created from a mock provider.
  3. Configure iOS permissions for Geolocation

    master

    To enable geolocation on iOS, you must add the following keys to your Info.plist. If these keys are missing, authorization requests will fail silently.

    • NSLocationWhenInUseUsageDescription: Required to enable geolocation when the app is in use.
    • NSLocationAlwaysAndWhenInUseUsageDescription: Required to enable geolocation when the app is in use.
    • NSLocationAlwaysUsageDescription: Required if your app supports iOS 10 or earlier, or if you need to enable geolocation in the background.

    Background Location: To support background location, you must also add 'location' as a background mode in the 'Capabilities' tab in Xcode.

    Note: On iOS >= 15, position objects include a mocked boolean indicating if the position was created from a mock provider.

  4. Get current position with Geolocation

    master

    To retrieve the user's current location, import Geolocation and call getCurrentPosition.

    import Geolocation from '@react-native-community/geolocation';
    
    Geolocation.getCurrentPosition(info => console.log(info));
    import Geolocation from '@react-native-community/geolocation';
    
    Geolocation.getCurrentPosition(info => console.log(info));
  5. Configure Geolocation with setRNConfiguration()

    master

    Use setRNConfiguration() to define global settings that apply to all subsequent location requests. This is useful for setting permission behaviors or choosing specific location providers on Android.

    Options:

    • skipPermissionRequests (boolean): If true, you must manually handle permissions before calling Geolocation APIs. Defaults to false.
    • authorizationLevel (string, iOS-only): Determines if the user is prompted for always, whenInUse, or auto. auto uses the default behavior based on your Info.plist.
    • enableBackgroundLocationUpdates (boolean, iOS-only): Toggles automatic background location updates when skipPermissionRequests is true. Defaults to true.
    • locationProvider (string, Android-only): Choose between playServices, android, or auto. auto defaults to android and falls back to the Android Location API if Play Services are unavailable.
  6. Request Location permissions with requestAuthorization()

    master

    Call requestAuthorization() to prompt the user for location permissions.

    On iOS, the specific permission requested depends on your Info.plist configuration: if NSLocationAlwaysUsageDescription is set, it requests Always authorization; if NSLocationWhenInUseUsageDescription is set, it requests InUse authorization.

    Error Object Properties:

    • code: numeric error code.
    • message: error description.
    • PERMISSION_DENIED: constant for permission errors.
    • POSITION_UNAVAILABLE: constant for unavailable position.
    • TIMEOUT: constant for timeout errors.
  7. Track location changes with watchPosition()

    master

    Use watchPosition() to subscribe to continuous location updates. It returns a watchId which can be used to stop the subscription.

    Options:

    • interval (ms, Android only): Preferred rate of updates.
    • fastestInterval (ms, Android only): The fastest rate your app can handle.
    • timeout (ms): Maximum time to wait for a position. Defaults to 10 minutes.
    • maximumAge (ms): Maximum age of a cached position. Defaults to Infinity.
    • enableHighAccuracy (boolean): Use GPS if true, otherwise use WIFI.
    • distanceFilter (m): Minimum distance (in meters) to move before a new update is triggered. Defaults to 100m. Set to 0 to disable filtering.
    • useSignificantChanges (boolean): Uses battery-efficient native APIs to return locations only when significant distance changes occur. Defaults to false.
  8. Get the current location with getCurrentPosition()

    master

    Use getCurrentPosition() to retrieve the device's current location once. It executes the success callback with the latest available position.

    Options:

    • timeout (ms): Maximum time to wait for a position. Defaults to 10 minutes.
    • maximumAge (ms): Maximum age of a cached position to accept. 0 forces a fresh retrieval; Infinity always returns a cached position. Defaults to Infinity.
    • enableHighAccuracy (boolean): If true, requests a GPS position; if false, requests a WIFI-based location.
  9. Configure autolinking for react-native-geolocation

    master

    When working in a monorepo or a project where the library is located outside the standard node_modules structure, you can use react-native.config.js to manually specify the root path for @react-native-community/geolocation (referenced as react-native-geolocation in the config) to ensure autolinking works correctly. This is done by setting the root property within the dependencies object.

    const path = require('path');
    
    module.exports = {
      dependencies: {
        'react-native-geolocation': {
          root: path.join(__dirname, '..'),
        },
      },
    };
  10. Configure Metro resolver for monorepo-style peer dependencies

    master

    When using this project in an example or monorepo context, the metro.config.js must be configured to prevent multiple versions of peer dependencies from being loaded. This is achieved by:

    1. Blacklisting the peer dependency versions located in the project root's node_modules using resolver.blacklistRE.
    2. Aliasing those same dependencies to the specific versions installed within the local example/node_modules using resolver.extraNodeModules.

    This ensures that the bundler only resolves to a single instance of each peer dependency, avoiding runtime errors caused by duplicate module instances.

    const config = {
      projectRoot: __dirname,
      watchFolders: [root],
      resolver: {
        blacklistRE: exclusionList(
          modules.map(
            (m) =>
              new RegExp(`^${escape(path.join(root, 'node_modules', m))}\\/.*$`)
          )
        ),
        extraNodeModules: modules.reduce((acc, name) => {
          acc[name] = path.join(__dirname, 'node_modules', name);
          return acc;
        }, {}),
      },
    };