DEV Community

Cover image for Handling Location Permissions in React Native
Amit Kumar
Amit Kumar

Posted on • Edited on

Handling Location Permissions in React Native

Managing location permissions is a crucial aspect of many mobile applications that provide personalized services or location-based features. In this article, weโ€™ll explore how to handle location permissions in a React Native project using the react-native-permissions library. We will also analyze key configuration steps, platform-specific requirements, and ensure everything works seamlessly on both Android and iOS.


Why Location Permissions?

Location permissions are required when your app needs access to the userโ€™s geographical location. Depending on your use case, you may need foreground or background location access:

  • Foreground Access:
    Needed when your app requires location data only when it is actively being used.

  • Background Access:
    Needed when your app needs location updates even when running in the background.


Implementation

Hereโ€™s the complete implementation for requesting and handling location permissions in a React Native app.

Prerequisites

  • Install react-native-permissions library:
$ npm i -S react-native-permissions
# --- or ---
$ yarn add react-native-permissions
Enter fullscreen mode Exit fullscreen mode

Configuration

Android

Add Permissions to AndroidManifest.xml

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

Enter fullscreen mode Exit fullscreen mode

Key Notes for Android:

- Android 6.0+ (API Level 23):
Introduced runtime permissions for fine and coarse location.

- Android 10+ (API Level 29):
Requires explicit permission for background location access.

Troubleshooting: If Permission Popup Doesn't Appear

add the following to your AndroidManifest.xml:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"
    tools:replace="android:maxSdkVersion"
    android:maxSdkVersion="34"/>

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
    tools:replace="android:maxSdkVersion"
    android:maxSdkVersion="34"/>
Enter fullscreen mode Exit fullscreen mode

maxSdkVersion must be same as declared in build.gradle file


iOS

Update Info.plist
Add the following keys to your Info.plist file:

<key>NSLocationWhenInUseUsageDescription</key>
<string>We need access to your location to provide personalized services.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>We need access to your location to provide personalized services, even when the app is in the background.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>We need access to your location to provide personalized services.</string>

Enter fullscreen mode Exit fullscreen mode

Supported iOS Versions*

  • iOS 8+:
    Required to request location permissions.

  • iOS 13+:
    Introduced "Always and When In Use" permissions.


Complete Code

import {
  Alert,
  PermissionsAndroid,
  Platform,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';
import React, {useEffect} from 'react';
import {check, PERMISSIONS, request, RESULTS} from 'react-native-permissions';

const App = () => {
  useEffect(() => {
    checkLocationPermission();
  }, []);

  const checkLocationPermission = async () => {
    const permission =
      Platform.OS === 'ios'
        ? PERMISSIONS.IOS.LOCATION_WHEN_IN_USE
        : PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION;

    const result = await check(permission);

    switch (result) {
      case RESULTS.UNAVAILABLE:
        console.log('This feature is not available on this device or OS.');
        break;
      case RESULTS.DENIED:
        console.log('Permission has not been requested / is denied.');
        handleDeniedPermissionModal();
        break;
      case RESULTS.GRANTED:
        console.log('Permission is granted.');
        break;
      case RESULTS.BLOCKED:
        console.log('Permission is denied and cannot be requested (blocked).');
        break;
    }
  };

  const handleDeniedPermissionModal = () => {
    Alert.alert(
      'Permission Required',
      'We need access to your location to provide accurate results and personalized services. Please enable location permissions in your device settings.',
      [
        {
          text: 'Cancel',
          style: 'cancel',
        },
        {
          text: 'Open Settings',
          onPress: () => openSettings(),
        },
      ],
    );
  };

  const requestLocationPermission = async () => {
    if (Platform.OS === 'ios') {
      const status = await request(PERMISSIONS.IOS.LOCATION_WHEN_IN_USE);
      if (status === RESULTS.GRANTED) {
        console.log('Location permission granted.');
      } else {
        console.log('Location permission denied.');
        handleDeniedPermissionModal();
      }
    } else if (Platform.OS === 'android') {
      const granted = await PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
      );
      if (granted === PermissionsAndroid.RESULTS.GRANTED) {
        console.log('Location permission granted.');
      } else {
        console.log('Location permission denied.');
        handleDeniedPermissionModal();
      }
    }
  };

  return (
    <View style={styles.container}>
      <TouchableOpacity
        onPress={requestLocationPermission}
        style={styles.buttonContainer}>
        <Text style={{color: '#000'}}>Ask Location permission</Text>
      </TouchableOpacity>
    </View>
  );
};

export default App;

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#fff',
  },
  buttonContainer: {
    width: '50%',
    borderColor: '#888',
    borderWidth: 1,
    alignItems: 'center',
    borderRadius: 50,
    paddingVertical: 10,
  },
});

Enter fullscreen mode Exit fullscreen mode

Conclusion

Handling location permissions in React Native is straightforward with react-native-permissions. By following the implementation and configurations outlined above, you can ensure your app provides a seamless experience while adhering to platform-specific requirements. Always test thoroughly to cover all edge cases and ensure a user-friendly experience.

Top comments (0)