Permissions And Privacy

Permissions are native release work. The JavaScript prompt is only the runtime part.

Permission Layers

LayerAndroidiOS
Native declarationandroid.permissions, package manifests, android.blockedPermissionsios.infoPlist, usage strings, background modes
Runtime requestExpo or React Native permission APIExpo or React Native permission API
User experienceRationale, denial, permanent denial, settings recoveryRationale, denial, limited access, settings recovery
Store reviewPlay policy, Data safety, sensitive permission declarationsApp privacy, usage strings, privacy manifests, App Review

Configure Intentionally

{
  "expo": {
    "ios": {
      "infoPlist": {
        "NSCameraUsageDescription": "Scan receipts you choose to capture."
      }
    },
    "android": {
      "permissions": ["CAMERA"],
      "blockedPermissions": ["com.google.android.gms.permission.AD_ID"]
    }
  }
}

Use specific, user-facing explanations. Generic strings create review risk and user mistrust.

Test The Denied Path

Every permission feature needs:

  • First-run prompt behavior.
  • Denied behavior.
  • Permanently denied/settings recovery.
  • Feature fallback or clear disabled state.
  • Store-review explanation that matches actual behavior.

Gotcha: Permission changes require a new binary. You cannot add a new Android manifest permission or iOS usage string with EAS Update alone.