Edit this page
Learn about configuring and adding permissions in an app config file.
When developing a native app that requires access to potentially sensitive information on a user's device, such as their location or contacts, the app must request the user's permission first. For example, to access the user's media library, the app will need to run MediaLibrary.requestPermissionsAsync()
.
Permissions in standalone and development builds require native build-time configuration before they can be requested using runtime JavaScript code. This is not required when testing projects in the Expo Go app.
If you don't configure or explain the native permissions properly it may result in your app getting rejected or pulled from the stores.
Permissions are configured with the android.permissions
and android.blockedPermissions
keys in your app config.
Most permissions are added automatically by libraries that you use in your app either with config plugins or with a package-level AndroidManifest.xml. You only need to use android.permissions
to add additional permissions that are not included by default in a library.
{
"android": {
"permissions": ["android.permission.SCHEDULE_EXACT_ALARM"]
}
}
The only way to remove permissions that are added by package-level AndroidManifest.xml files is to block them with the android.blockedPermissions
property. To do this, specify the full permission name. For example, if you want to remove the audio recording permissions added by expo-av
:
{
"android": {
"blockedPermissions": ["android.permission.RECORD_AUDIO"]
}
}
android.permissions
to learn about which permissions are included in the default prebuild template.Manifest.permissions
.Modify AndroidManifest.xml to exclude specific permissions: add the tools:node="remove"
attribute to a <use-permission>
tag to ensure it is removed, even if it's included in a library AndroidManifest.xml.
<manifest xmlns:tools="http://schemas.android.com/tools">
<uses-permission tools:node="remove" android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>
You have to define the
xmlns:tools
attribute on<manifest>
before you can use thetools:node
attribute on permissions.
Your iOS app can ask for system permissions from the user. For example, to use the device's camera or access photos, Apple requires an explanation for how your app makes use of that data. Most packages will automatically provide a boilerplate reason for a given permission with config plugins. These default messages will most likely need to be tailored to your specific use case for your app to be accepted by the App Store.
To set permission messages, use the ios.infoPlist
key in your app config, for example:
{
"ios": {
"infoPlist": {
"NSCameraUsageDescription": "This app uses the camera to scan barcodes on event tickets."
}
}
}
Many of these properties are also directly configurable using the config plugin properties associated with the library that adds them. For example, with expo-media-library
you can configure photo permission messages like this:
{
"plugins": [
[
"expo-media-library",
{
"photosPermission": "Allow $(PRODUCT_NAME) to access your photos.",
"savePhotosPermission": "Allow $(PRODUCT_NAME) to save photos."
}
]
]
}
eas build
.Add and modify the permission message values in Info.plist file directly. We recommend doing this directly in Xcode for autocompletion.
On the web, permissions like the Camera
and Location
can only be requested from a secure context. For example, using https://
or http://localhost
. This limitation is similar to Android's manifest permissions and iOS's Info.plist usage messages and is enforced to increase privacy.
Often you want to be able to test what happens when a user rejects permissions, to ensure your app reacts gracefully. An operating-system level restriction on both Android and iOS prohibits an app from asking for the same permission more than once (you can imagine how this could be annoying for the user to be repeatedly prompted for permissions after rejecting them). To test different flows involving permissions in development, you may need to uninstall and reinstall the native app.
When testing in Expo Go, you can delete the app and reinstall it by running npx expo start
and pressing i or a in the Expo CLI Terminal UI.