CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-native-permissions

Unified permissions API for React Native on iOS, Android and Windows platforms

Pending
Overview
Eval results
Files

permission-requesting.mddocs/

Permission Requesting

Request permissions from the user with optional rationale dialogs. Handles the native permission request flow and user interaction.

Capabilities

Request Single Permission

Request a single permission from the user, with optional rationale dialog for explanation.

/**
 * Request a single permission from the user
 * @param permission - The permission to request
 * @param rationale - Optional rationale dialog or function for explanation
 * @returns Promise resolving to the permission status after user interaction
 */
function request(permission: Permission, rationale?: Rationale): Promise<PermissionStatus>;

type Rationale = RationaleObject | (() => Promise<boolean>);

interface RationaleObject {
  title: string;
  message: string;
  buttonPositive: string;
  buttonNegative?: string;
}

Usage Examples:

import { request, PERMISSIONS, RESULTS } from "react-native-permissions";

// Basic permission request
const cameraStatus = await request(PERMISSIONS.IOS.CAMERA);
if (cameraStatus === RESULTS.GRANTED) {
  console.log("Camera permission granted");
}

// Request with rationale dialog (Android)
const micStatus = await request(PERMISSIONS.ANDROID.RECORD_AUDIO, {
  title: "Microphone Permission",
  message: "This app needs microphone access to record audio for voice messages.",
  buttonPositive: "Grant Access",
  buttonNegative: "Not Now"
});

// Request with custom rationale function
const locationStatus = await request(
  PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION,
  async () => {
    // Custom logic to show rationale
    const userWantsToGrant = await showCustomRationaleDialog();
    return userWantsToGrant;
  }
);

Request Multiple Permissions

Request multiple permissions in a single call, with optional rationale for Android.

/**
 * Request multiple permissions simultaneously
 * @param permissions - Array of permissions to request
 * @returns Promise resolving to object mapping each permission to its status
 */
function requestMultiple<P extends Permission[]>(
  permissions: P
): Promise<Record<P[number], PermissionStatus>>;

Usage Examples:

import { requestMultiple, PERMISSIONS, RESULTS } from "react-native-permissions";

// Request multiple iOS permissions
const statuses = await requestMultiple([
  PERMISSIONS.IOS.CAMERA,
  PERMISSIONS.IOS.MICROPHONE,
  PERMISSIONS.IOS.PHOTO_LIBRARY,
]);

// Check individual results
Object.entries(statuses).forEach(([permission, status]) => {
  console.log(`${permission}: ${status}`);
});

// Check if all permissions were granted
const allGranted = Object.values(statuses).every(status => status === RESULTS.GRANTED);
if (allGranted) {
  console.log("All permissions granted - ready to proceed");
} else {
  console.log("Some permissions were denied");
}

// Request specific Android permissions for media access
const mediaStatuses = await requestMultiple([
  PERMISSIONS.ANDROID.CAMERA,
  PERMISSIONS.ANDROID.RECORD_AUDIO,
  PERMISSIONS.ANDROID.READ_MEDIA_IMAGES,
]);

Request Location Accuracy (iOS)

Request full location accuracy from the user when the app has reduced accuracy.

/**
 * Request location accuracy upgrade from reduced to full (iOS only)
 * @param options - Configuration with purpose key from Info.plist
 * @returns Promise resolving to the granted accuracy level
 */
function requestLocationAccuracy(options: LocationAccuracyOptions): Promise<LocationAccuracy>;

interface LocationAccuracyOptions {
  purposeKey: string;
}

type LocationAccuracy = 'full' | 'reduced';

Usage Examples:

import { 
  requestLocationAccuracy, 
  checkLocationAccuracy,
  PERMISSIONS,
  request 
} from "react-native-permissions";

// First ensure location permission is granted
const locationStatus = await request(PERMISSIONS.IOS.LOCATION_WHEN_IN_USE);
if (locationStatus === RESULTS.GRANTED) {
  const currentAccuracy = await checkLocationAccuracy();
  
  if (currentAccuracy === 'reduced') {
    // Request full accuracy using purpose key from Info.plist
    const newAccuracy = await requestLocationAccuracy({
      purposeKey: 'NSLocationDefaultAccuracyReduced'
    });
    
    if (newAccuracy === 'full') {
      console.log("Full location accuracy granted");
    } else {
      console.log("User chose to keep reduced accuracy");
    }
  }
}

Request Notification Permissions

Request notification permissions with specific notification types and optional rationale.

/**
 * Request notification permissions with specific options
 * @param options - Array of notification types to request
 * @param rationale - Optional rationale for Android
 * @returns Promise resolving to notification status and detailed settings
 */
function requestNotifications(
  options?: NotificationOption[],
  rationale?: Rationale
): Promise<NotificationsResponse>;

type NotificationOption = 
  | 'alert'
  | 'badge' 
  | 'sound'
  | 'carPlay'
  | 'criticalAlert'
  | 'provisional'
  | 'providesAppSettings';

interface NotificationsResponse {
  status: PermissionStatus;
  settings: NotificationSettings;
}

Usage Examples:

import { requestNotifications, RESULTS } from "react-native-permissions";

// Request basic notification permissions
const basicNotifications = await requestNotifications(['alert', 'badge', 'sound']);
if (basicNotifications.status === RESULTS.GRANTED) {
  console.log("Basic notifications granted");
}

// Request advanced notification permissions (iOS)
const advancedNotifications = await requestNotifications([
  'alert',
  'badge',
  'sound',
  'criticalAlert',
  'provisional'
]);

console.log("Notification settings:", advancedNotifications.settings);

// Request with rationale (Android)
const androidNotifications = await requestNotifications(
  ['alert', 'badge'],
  {
    title: "Enable Notifications",
    message: "Get notified about important updates and messages.",
    buttonPositive: "Enable",
    buttonNegative: "Skip"
  }
);

// Check specific notification capabilities
if (advancedNotifications.settings.criticalAlert) {
  console.log("Critical alerts are enabled");
}
if (advancedNotifications.settings.provisional) {
  console.log("Provisional notifications are enabled");
}

Permission Request Flow

The request flow varies by platform:

iOS Request Flow

  1. First request shows system dialog
  2. If denied, subsequent requests return 'denied' immediately
  3. User must manually enable in Settings if 'blocked'
  4. Some permissions (like notifications) can be requested multiple times

Android Request Flow

  1. Shows rationale dialog if provided and needed
  2. Shows system permission dialog
  3. If denied twice, permission becomes 'blocked'
  4. Some permissions require specific Android versions
import { request, check, openSettings, PERMISSIONS, RESULTS } from "react-native-permissions";

async function requestCameraWithFallback() {
  // Check current status first
  let status = await check(PERMISSIONS.IOS.CAMERA);
  
  if (status === RESULTS.DENIED) {
    // Request permission
    status = await request(PERMISSIONS.IOS.CAMERA);
  }
  
  if (status === RESULTS.BLOCKED) {
    // Permission is blocked, direct user to settings
    console.log("Camera permission is blocked. Please enable in Settings.");
    await openSettings();
  }
  
  return status === RESULTS.GRANTED;
}

Rationale Best Practices

Effective Rationale Messages

  • Explain why the permission is needed
  • Be specific about the feature it enables
  • Keep messages concise and user-friendly
  • Use positive language
// Good rationale example
const goodRationale = {
  title: "Camera Access Required",
  message: "Camera access is needed to take photos for your profile and share them with friends.",
  buttonPositive: "Grant Access",
  buttonNegative: "Not Now"
};

// Poor rationale example - too vague
const poorRationale = {
  title: "Permission Required",
  message: "This app needs camera permission to work properly.",
  buttonPositive: "OK",
  buttonNegative: "Cancel"
};

Custom Rationale Function

Use custom rationale functions for complex logic or custom UI:

import { request, PERMISSIONS } from "react-native-permissions";

const customRationaleFunction = async (): Promise<boolean> => {
  // Show custom modal or alert
  const result = await showCustomPermissionDialog({
    title: "Location Access",
    message: "Enable location to find nearby restaurants and get personalized recommendations.",
    primaryButton: "Enable Location",
    secondaryButton: "Maybe Later"
  });
  
  return result.action === 'primary';
};

const locationStatus = await request(
  PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION,
  customRationaleFunction
);

Error Handling

Request functions may throw errors in these cases:

  • Invalid Permission: Requesting unsupported permissions
  • Native Module Error: Native module initialization failures
  • Platform Incompatibility: Platform-specific method calls on wrong platform
import { request, PERMISSIONS } from "react-native-permissions";

async function safeRequestPermission(permission: Permission) {
  try {
    const status = await request(permission);
    return { success: true, status };
  } catch (error) {
    console.error("Permission request failed:", error);
    return { success: false, error };
  }
}

// Usage
const result = await safeRequestPermission(PERMISSIONS.IOS.CAMERA);
if (result.success) {
  console.log("Permission status:", result.status);
} else {
  console.log("Request failed:", result.error);
}

Install with Tessl CLI

npx tessl i tessl/npm-react-native-permissions

docs

index.md

notification-permissions.md

permission-checking.md

permission-constants.md

permission-requesting.md

platform-specific-features.md

tile.json