DEV Community

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

Posted 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.


Image description

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

Supported Android Versions

- 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.


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)