Skip to main content

Overview

Modern mobile apps require explicit user permission to access sensitive features like camera, location, and notifications. This guide shows you how to properly request and handle permissions across platforms.

Permission Types

Common permissions in Expo apps:
  • Camera: Take photos and videos
  • Microphone: Record audio
  • Location: Access device location
  • Notifications: Send push notifications
  • Photos/Media Library: Access saved photos
  • Contacts: Access user contacts
  • Calendar: Access calendar events
  • Reminders: Access iOS reminders

Installation

Most Expo SDK packages include their own permission methods:

Requesting Permissions

Basic pattern

All Expo permission APIs follow a similar pattern:

Permission hook

Create a reusable hook for any permission:
hooks/usePermission.ts
Usage:
components/CameraButton.tsx

Common Permissions

Permission States

Understanding permission status

Handling different states

Platform Differences

iOS-specific considerations

Permission descriptions required:Add usage descriptions in app.json:
app.json
Your app will crash if you request a permission without the corresponding usage description.
Permission timing:
  • iOS only allows asking twice
  • After second denial, must use Settings
  • “Don’t Allow” vs “Ask Next Time”
Location precision (iOS 14+):

Best Practices

1. Request permissions in context

2. Explain why you need permission

3. Handle all permission states

4. Graceful degradation

5. Check before requesting

Debugging Permissions

Log permission status

Reset permissions (development)

Troubleshooting

iOS: Ensure you’ve added the usage description to app.json:
Rebuild after adding: npx expo prebuild --clean
  • User previously denied with “Don’t ask again” (Android)
  • User denied twice already (iOS)
  • Direct user to Settings with Linking.openSettings()
  • Check for additional permissions (e.g., location + background location)
  • Verify device settings (Location Services enabled)
  • Check for OS restrictions (parental controls)
  • Verify you’re calling requestAsync() not just getAsync()
  • Check permission isn’t already granted or permanently denied
  • Ensure you’ve declared the permission in app.json (Android)
Always rebuild your app after modifying permissions in app.json: npx expo prebuild --clean

Permission Reference

Quick reference for common permission methods: