React Native permissions generator

React Native app tracking transparency permission

App Tracking Transparency is the iOS prompt that must be shown before an app reads the advertising identifier or otherwise tracks the user across other companies' apps and websites; its text comes from NSUserTrackingUsageDescription. On Android the equivalent is the com.google.android.gms.permission.AD_ID declaration required to read the advertising ID on Android 13 and later.

expo-tracking-transparency declares both and requestTrackingPermissionsAsync shows the iOS prompt. Apple rejects apps that read the identifier before the prompt, and the prompt can be shown only once, so an app should ask at a moment when the user understands what tracking buys them.

App tracking transparency at a glance

Android grants
com.google.android.gms.permission.AD_ID
iOS Info.plist key
NSUserTrackingUsageDescription
Expo package
expo-tracking-transparency
Config plugin
expo-tracking-transparency
What it enables
Ask iOS for the advertising identifier used to track across apps.
What the user agrees to
Track your activity across other apps and websites

The declarations, for Expo and the bare workflow

Expo config

app.json
{
  "expo": {
    "ios": {
      "infoPlist": {
        "NSUserTrackingUsageDescription": "TODO: why this app tracks you across apps."
      }
    },
    "android": {
      "permissions": [
        "com.google.android.gms.permission.AD_ID"
      ]
    },
    "plugins": [
      "expo-router",
      "expo-tracking-transparency"
    ]
  }
}

Prebuild writes these into the native projects; the config plugin is what makes the package's native code part of the build.

Bare workflow, Android

android/app/src/main/AndroidManifest.xml
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />

Bare workflow, iOS

ios/<App>/Info.plist
<key>NSUserTrackingUsageDescription</key>
<string>TODO: why this app tracks you across apps.</string>

The TODO is deliberate: the usage description is shown in the consent prompt and App Review rejects boilerplate.

Install the library

terminal
npx expo install expo-tracking-transparency

App tracking transparency permission, answered

The longer version is in the guide React Native permissions that satisfy both stores.

What permission does React Native need for app tracking transparency?
On Android, declare com.google.android.gms.permission.AD_ID in AndroidManifest.xml (or expo.android.permissions in app.json). On iOS, add NSUserTrackingUsageDescription to Info.plist (or expo.ios.infoPlist) with a sentence explaining why — the user reads it in the consent prompt. expo-tracking-transparency exposes the runtime request.
Do I still have to request app tracking transparency at runtime?
Yes. The declaration only makes the request possible. The first time the feature is used, call the request API from expo-tracking-transparency; the operating system shows the prompt ("Track your activity across other apps and websites") and remembers the answer. A declared but never requested permission does nothing, and a requested but never declared one fails.
Why was my app rejected over the app tracking transparency permission?
Most often the NSUserTrackingUsageDescription string: App Review rejects a missing one at once and a vague or boilerplate one frequently. Write what the app does with the data in your own words. Google Play reviews the declaration against the app's visible features, so a grant no screen uses is also a finding.

Declare every feature the app uses

The React Native permissions generator builds the complete set from the same catalogue — tick each device feature and copy the paired Android grants and iOS usage descriptions, the Expo app.json fragment and the install line together. In the Nodlume workspace the declarations come from the screens themselves: a screen that uses the camera is what adds the camera permission to the Expo Router project it exports.

Open the generator

Other React Native permissions

We'd like to use Google cookies to understand how Nodlume is used and to measure our advertising. Nothing loads until you choose, and declining does not affect anything in the app.