0
# Permission Requesting
1
2
Request permissions from the user with optional rationale dialogs. Handles the native permission request flow and user interaction.
3
4
## Capabilities
5
6
### Request Single Permission
7
8
Request a single permission from the user, with optional rationale dialog for explanation.
9
10
```typescript { .api }
11
/**
12
* Request a single permission from the user
13
* @param permission - The permission to request
14
* @param rationale - Optional rationale dialog or function for explanation
15
* @returns Promise resolving to the permission status after user interaction
16
*/
17
function request(permission: Permission, rationale?: Rationale): Promise<PermissionStatus>;
18
19
type Rationale = RationaleObject | (() => Promise<boolean>);
20
21
interface RationaleObject {
22
title: string;
23
message: string;
24
buttonPositive: string;
25
buttonNegative?: string;
26
}
27
```
28
29
**Usage Examples:**
30
31
```typescript
32
import { request, PERMISSIONS, RESULTS } from "react-native-permissions";
33
34
// Basic permission request
35
const cameraStatus = await request(PERMISSIONS.IOS.CAMERA);
36
if (cameraStatus === RESULTS.GRANTED) {
37
console.log("Camera permission granted");
38
}
39
40
// Request with rationale dialog (Android)
41
const micStatus = await request(PERMISSIONS.ANDROID.RECORD_AUDIO, {
42
title: "Microphone Permission",
43
message: "This app needs microphone access to record audio for voice messages.",
44
buttonPositive: "Grant Access",
45
buttonNegative: "Not Now"
46
});
47
48
// Request with custom rationale function
49
const locationStatus = await request(
50
PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION,
51
async () => {
52
// Custom logic to show rationale
53
const userWantsToGrant = await showCustomRationaleDialog();
54
return userWantsToGrant;
55
}
56
);
57
```
58
59
### Request Multiple Permissions
60
61
Request multiple permissions in a single call, with optional rationale for Android.
62
63
```typescript { .api }
64
/**
65
* Request multiple permissions simultaneously
66
* @param permissions - Array of permissions to request
67
* @returns Promise resolving to object mapping each permission to its status
68
*/
69
function requestMultiple<P extends Permission[]>(
70
permissions: P
71
): Promise<Record<P[number], PermissionStatus>>;
72
```
73
74
**Usage Examples:**
75
76
```typescript
77
import { requestMultiple, PERMISSIONS, RESULTS } from "react-native-permissions";
78
79
// Request multiple iOS permissions
80
const statuses = await requestMultiple([
81
PERMISSIONS.IOS.CAMERA,
82
PERMISSIONS.IOS.MICROPHONE,
83
PERMISSIONS.IOS.PHOTO_LIBRARY,
84
]);
85
86
// Check individual results
87
Object.entries(statuses).forEach(([permission, status]) => {
88
console.log(`${permission}: ${status}`);
89
});
90
91
// Check if all permissions were granted
92
const allGranted = Object.values(statuses).every(status => status === RESULTS.GRANTED);
93
if (allGranted) {
94
console.log("All permissions granted - ready to proceed");
95
} else {
96
console.log("Some permissions were denied");
97
}
98
99
// Request specific Android permissions for media access
100
const mediaStatuses = await requestMultiple([
101
PERMISSIONS.ANDROID.CAMERA,
102
PERMISSIONS.ANDROID.RECORD_AUDIO,
103
PERMISSIONS.ANDROID.READ_MEDIA_IMAGES,
104
]);
105
```
106
107
### Request Location Accuracy (iOS)
108
109
Request full location accuracy from the user when the app has reduced accuracy.
110
111
```typescript { .api }
112
/**
113
* Request location accuracy upgrade from reduced to full (iOS only)
114
* @param options - Configuration with purpose key from Info.plist
115
* @returns Promise resolving to the granted accuracy level
116
*/
117
function requestLocationAccuracy(options: LocationAccuracyOptions): Promise<LocationAccuracy>;
118
119
interface LocationAccuracyOptions {
120
purposeKey: string;
121
}
122
123
type LocationAccuracy = 'full' | 'reduced';
124
```
125
126
**Usage Examples:**
127
128
```typescript
129
import {
130
requestLocationAccuracy,
131
checkLocationAccuracy,
132
PERMISSIONS,
133
request
134
} from "react-native-permissions";
135
136
// First ensure location permission is granted
137
const locationStatus = await request(PERMISSIONS.IOS.LOCATION_WHEN_IN_USE);
138
if (locationStatus === RESULTS.GRANTED) {
139
const currentAccuracy = await checkLocationAccuracy();
140
141
if (currentAccuracy === 'reduced') {
142
// Request full accuracy using purpose key from Info.plist
143
const newAccuracy = await requestLocationAccuracy({
144
purposeKey: 'NSLocationDefaultAccuracyReduced'
145
});
146
147
if (newAccuracy === 'full') {
148
console.log("Full location accuracy granted");
149
} else {
150
console.log("User chose to keep reduced accuracy");
151
}
152
}
153
}
154
```
155
156
### Request Notification Permissions
157
158
Request notification permissions with specific notification types and optional rationale.
159
160
```typescript { .api }
161
/**
162
* Request notification permissions with specific options
163
* @param options - Array of notification types to request
164
* @param rationale - Optional rationale for Android
165
* @returns Promise resolving to notification status and detailed settings
166
*/
167
function requestNotifications(
168
options?: NotificationOption[],
169
rationale?: Rationale
170
): Promise<NotificationsResponse>;
171
172
type NotificationOption =
173
| 'alert'
174
| 'badge'
175
| 'sound'
176
| 'carPlay'
177
| 'criticalAlert'
178
| 'provisional'
179
| 'providesAppSettings';
180
181
interface NotificationsResponse {
182
status: PermissionStatus;
183
settings: NotificationSettings;
184
}
185
```
186
187
**Usage Examples:**
188
189
```typescript
190
import { requestNotifications, RESULTS } from "react-native-permissions";
191
192
// Request basic notification permissions
193
const basicNotifications = await requestNotifications(['alert', 'badge', 'sound']);
194
if (basicNotifications.status === RESULTS.GRANTED) {
195
console.log("Basic notifications granted");
196
}
197
198
// Request advanced notification permissions (iOS)
199
const advancedNotifications = await requestNotifications([
200
'alert',
201
'badge',
202
'sound',
203
'criticalAlert',
204
'provisional'
205
]);
206
207
console.log("Notification settings:", advancedNotifications.settings);
208
209
// Request with rationale (Android)
210
const androidNotifications = await requestNotifications(
211
['alert', 'badge'],
212
{
213
title: "Enable Notifications",
214
message: "Get notified about important updates and messages.",
215
buttonPositive: "Enable",
216
buttonNegative: "Skip"
217
}
218
);
219
220
// Check specific notification capabilities
221
if (advancedNotifications.settings.criticalAlert) {
222
console.log("Critical alerts are enabled");
223
}
224
if (advancedNotifications.settings.provisional) {
225
console.log("Provisional notifications are enabled");
226
}
227
```
228
229
## Permission Request Flow
230
231
The request flow varies by platform:
232
233
### iOS Request Flow
234
1. First request shows system dialog
235
2. If denied, subsequent requests return 'denied' immediately
236
3. User must manually enable in Settings if 'blocked'
237
4. Some permissions (like notifications) can be requested multiple times
238
239
### Android Request Flow
240
1. Shows rationale dialog if provided and needed
241
2. Shows system permission dialog
242
3. If denied twice, permission becomes 'blocked'
243
4. Some permissions require specific Android versions
244
245
```typescript
246
import { request, check, openSettings, PERMISSIONS, RESULTS } from "react-native-permissions";
247
248
async function requestCameraWithFallback() {
249
// Check current status first
250
let status = await check(PERMISSIONS.IOS.CAMERA);
251
252
if (status === RESULTS.DENIED) {
253
// Request permission
254
status = await request(PERMISSIONS.IOS.CAMERA);
255
}
256
257
if (status === RESULTS.BLOCKED) {
258
// Permission is blocked, direct user to settings
259
console.log("Camera permission is blocked. Please enable in Settings.");
260
await openSettings();
261
}
262
263
return status === RESULTS.GRANTED;
264
}
265
```
266
267
## Rationale Best Practices
268
269
### Effective Rationale Messages
270
- Explain **why** the permission is needed
271
- Be specific about the feature it enables
272
- Keep messages concise and user-friendly
273
- Use positive language
274
275
```typescript
276
// Good rationale example
277
const goodRationale = {
278
title: "Camera Access Required",
279
message: "Camera access is needed to take photos for your profile and share them with friends.",
280
buttonPositive: "Grant Access",
281
buttonNegative: "Not Now"
282
};
283
284
// Poor rationale example - too vague
285
const poorRationale = {
286
title: "Permission Required",
287
message: "This app needs camera permission to work properly.",
288
buttonPositive: "OK",
289
buttonNegative: "Cancel"
290
};
291
```
292
293
### Custom Rationale Function
294
Use custom rationale functions for complex logic or custom UI:
295
296
```typescript
297
import { request, PERMISSIONS } from "react-native-permissions";
298
299
const customRationaleFunction = async (): Promise<boolean> => {
300
// Show custom modal or alert
301
const result = await showCustomPermissionDialog({
302
title: "Location Access",
303
message: "Enable location to find nearby restaurants and get personalized recommendations.",
304
primaryButton: "Enable Location",
305
secondaryButton: "Maybe Later"
306
});
307
308
return result.action === 'primary';
309
};
310
311
const locationStatus = await request(
312
PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION,
313
customRationaleFunction
314
);
315
```
316
317
## Error Handling
318
319
Request functions may throw errors in these cases:
320
321
- **Invalid Permission**: Requesting unsupported permissions
322
- **Native Module Error**: Native module initialization failures
323
- **Platform Incompatibility**: Platform-specific method calls on wrong platform
324
325
```typescript
326
import { request, PERMISSIONS } from "react-native-permissions";
327
328
async function safeRequestPermission(permission: Permission) {
329
try {
330
const status = await request(permission);
331
return { success: true, status };
332
} catch (error) {
333
console.error("Permission request failed:", error);
334
return { success: false, error };
335
}
336
}
337
338
// Usage
339
const result = await safeRequestPermission(PERMISSIONS.IOS.CAMERA);
340
if (result.success) {
341
console.log("Permission status:", result.status);
342
} else {
343
console.log("Request failed:", result.error);
344
}
345
```