Requesting Location Permission in React Native Applications
Many mobile apps, like maps or social media, use location services to function effectively. As a developer building such mobile apps, you’ll need to add location access to your app for better functionality.
Before reading a user’s location information with a mobile app, they must first grant the location API permission to track their device. This convention respects a user’s privacy and gives the app full coverage of the user’s location.
In this article, you’ll learn how to request permission to access a user’s location information in foreground and background mode and track their device in a React Native app.
Step 1: Installing the Expo Location API
The Expo SDK provides functionality for gaining access to a location API. This location API (expo-location) is responsible for reading geolocation information from a user’s device. To do this, you must first install expo-location in your app.
Run this command to install expo-location in an expo-managed app:
expo install expo-location
Follow these instructions to install and configure expo modules in a bare React Native app.
Now, install and configure expo-location
for iOS and Android. How to achieve this is documented in the expo-location GitHub repository.
Step 2: Requesting Foreground Permission
You can track a user’s location in two modes: when the app is open (Foreground) or closed but running in the background (Background). Making requests to track both Foreground and Background locations must be made independently.
Proceed to import expo-location into your project:
import * as Location from 'expo-location';
Expo-location provides methods that trigger events or read data from the user’s device. The requestForegroundPermissionsAsync() method requests permission to track a device’s location in foreground mode and returns an object with property status
.
status
reports the status of the request to access the location. This object returns "granted```,
“denied, or `"undetermined
if the user accepted, rejected, or failed to accept or reject the permission request, respectively.
To determine the result of the status
property destructure the object from calling the requestForegroundPermissionsAsync()
method:
let { status } = await Location.requestForegroundPermissionsAsync();
console.log(status)
Requesting location permission will display a permission modal for the user to select between the options, as shown in the images below.
iOS permission modal
Android permission modal
Once a user accepts or rejects the location permission, it is automatically accepted or rejected subsequently based on the previously set option.
The table below shows how to reset the location permission status
on an iOS simulator, Android emulator, and a physical device running the Expo Go app.
Platform | Steps to Reset Location Permission |
---|---|
iOS Simulator | Settings > General > Reset > Reset Location and Privacy |
iOS Device running Expo Go | Settings > Expo Go > Toggle Location Permission |
Android Emulator | Run “adb shell pm reset-permissions” inside your project directory in your terminal |
Android Device running Expo Go | (Android 11) Settings > Location > Expo Go > Permissions > Location > Toggle Location Permission |
Step 3: Requesting Background Permission.
A user must first grant foreground location permission to request background location permission.
The code below will request foreground and background location permission on the user’s device:
const startBackgroundTracking = async () => {
const { status } = await Location.requestForegroundPermissionsAsync();
if (status == "granted") {
await Location.requestBackgroundPermissionsAsync();
}
};
Next, set configurations for your ios
and android
builds to allow background location tracking.
For ios
, declare an NSLocationAlwaysAndWhenInUseUsageDescription key that tells the user why the app is requesting access to the user’s location at all times. Also, include a UIBackgroundModes that specifies the app’s services that require it to run in the background.
For android
, declare ACCESS_BACKGROUND_LOCATION under permissions to be able to request background permission.
Update your app.json
file to include these configurations:
{
"expo": {
"ios": {
"infoPlist": {
"NSLocationAlwaysAndWhenInUseUsageDescription": "REASON_FOR_REQUEST",
"UIBackgroundModes": ["location", "fetch"]
}
},
"android": {
"permissions": ["ACCESS_BACKGROUND_LOCATION"]
}
}
}
To run tasks like tracking background location over an extended time, install expo-task-manager by running expo install expo-task-manager
.
Import Task Manager and define the task for tracking:
import * as TaskManager from "expo-task-manager";
const LOCATION_TASK_NAME = "background-location-task";
// Define the background task for location tracking
TaskManager.defineTask(LOCATION_TASK_NAME, async ({ data, error }) => {
if (error) {
console.error(error);
return;
}
if (data) {
// Extract location coordinates from data
const { locations } = data;
const location = locations[0];
if (location) {
// Do something with captured location coordinates
}
}
});
Now you can watch for background location updates using the startLocationUpdatesAsync() method.
This method takes LOCATION_TASK_NAME
and location task options as arguments:
const startBackgroundTracking = async () => {
await Location.startLocationUpdatesAsync(LOCATION_TASK_NAME, {
//Location Task Options
});
};
You can find all location task options in the Expo documentation.
Note: Task Manager may not work as expected in the Expo Go app on iOS. You’ll need to test it using a development build.
Session Replay for Developers
Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — an open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.
Overview of Expo Permissions
The Expo Permissions can be used to request the following permissions:
- AUDIO_RECORDING: access to the device’s microphone for audio recording
- CALENDAR: access to the device’s calendar (iOS only)
- CAMERA: access to the device’s camera
- CONTACTS: access to the device’s contact list
- LOCATION: access to the device’s location
- MEDIA-LIBRARY: access to the device’s photo and video library. The application will be able to view or write to the library.
- NOTIFICATIONS: access to the device’s notification system
- REMINDER: access to the device’s reminders (iOS only)
- SENSORS: access to the device’s sensors to measure motion, orientation, pressure, magnetic fields, and step count
To request permission to access any of the above-listed features with Expo, you must install the specific expo library and ensure that you have the necessary native configuration for each permission you request. The configurations are different for each library and each Operating system platform.
For example, to request Camera permissions on an iOS and Android platform, you will need to install the expo-camera
library and add an NSCameraUseUsageDescription to your Info.plist
(iOS) and CAMERA value to the Permissions
object (Android):
iOS:
"ios": {
"infoPlist": {
"NSCameraUseUsageDescription": "REASON_FOR_REQUEST",
"UIBackgroundModes": ["Camera"]
}
}
Android:
"android": {
"permissions": ["CAMERA"]
}
For a list of the native configuration required for each permission, see the documentation for the Expo API Reference:
Challenges To Handle When Requesting Permissions
Requesting permissions can present several challenges for developers. One of the main challenges is ensuring that the app requests the correct permissions for the specific device and operating system. This is because different devices and operating systems have different permission models and configuration requirements, making it difficult to write code seamlessly across all platforms.
Another challenge is handling the different states of permissions. For example, an app may request permission, and the user may choose to grant or deny it. The app must then be able to handle both scenarios and respond appropriately, such as disabling certain features if permission is denied. Users can also revoke permissions at any time, which can cause unexpected behavior in the app.
Lastly, iOS and Android systems have strict restrictions and privacy settings. These are efforts to protect users from private data leaks and misuse, which they may not be aware of. Providing clear and informative explanations to the user about why the app needs certain permission is an absolute must. This is especially important for sensitive permissions such as access to the location or microphone, as users may be more likely to deny them if they do not understand why the app needs them.
Conclusion
In this post, you successfully learned how to request permission to access a user’s location data. You also learned about other available Expo permissions and their features.
Following the proper native configuration and best practices for requesting permissions, you can ensure that your app has the necessary permissions to provide a seamless and enjoyable user experience.