Jump to top

iOS Permissions

Request permissions from your users to allow notifications to be displayed.

Understanding permissions

Before diving into requesting notification permissions from your users, it is important to understand how iOS handles permissions.

Notifications cannot be shown to users if the user has not "granted" your application permission. The overall notification permission of a single application can be either be "not determined", "granted" or "declined". Upon installing a new application, the default status is "not determined".

In order to receive a "granted" status, you must request permission from your user (see below). The user can either accept or decline your request to grant permissions. If granted, notifications will be displayed based on the permission settings which were requested.

If the user declines the request, you cannot re-request permission, trying to request permission again will immediately return a "denied" status without any user interaction - instead the user must manually enable notification permissions from the iOS Settings UI.

Requesting permissions

As explained in the Usage documentation, permission must be requested from your users in order to display remote notifications from FCM, via the requestPermission API:

import messaging from '@react-native-firebase/messaging';

async function requestUserPermission() {
  const authorizationStatus = await messaging().requestPermission();

  if (authorizationStatus) {
    console.log('Permission status:', authorizationStatus);
  }
}

Once a user has selected a permission status, iOS prevents the permission dialog from being displayed again. This allows the users of your application full control of how notifications are handled:

  • If the user declines permission, they must manually allow notifications via the Settings UI for your application.
  • If the user has accepted permission, notifications will be shown using the settings requested (e.g. with or without sound).

Permission settings

Although overall notification permission can be granted, the permissions can be further broken down into settings.

Settings are used by the device to control notifications behavior, for example alerting the user with sound. When requesting permission, you can provide a custom object of settings if you wish to override the defaults. This is demonstrated in the following example:

await messaging().requestPermission({
  sound: false,
  announcement: true,
  // ... other permission settings
});

The full list of permission settings can be seen in the table below along with their default values:

PermissionDefaultDescription
alerttrueSets whether notifications can be displayed to the user on the device.
announcementfalseIf enabled, Siri will read the notification content out when devices are connected to AirPods.
badgetrueSets whether a notification dot will appear next to the app icon on the device when there are unread notifications.
carPlaytrueSets whether notifications will appear when the device is connected to CarPlay.
provisionalfalseSets whether provisional permissions are granted. See Provisional permission for more information.
soundtrueSets whether a sound will be played when a notification is displayed on the device.
providesAppNotificationSettingsfalseIndicates the system to display a button for in-app notification settings.

The settings provided will be stored by the device and will be visible in the iOS Settings UI for your application.

If the permission dialog has already been presented to the user and you wish to update the existing permission settings (e.g. enabling sound), the setting will be silently updated and the requestPermission call will instantly resolve without showing a dialog.

Reading current status

In some cases, you may wish to read the current permission status. The requestPermission API used above resolves an enum that returns the current status.

For example:

import messaging from '@react-native-firebase/messaging';

async function checkApplicationPermission() {
  const authorizationStatus = await messaging().requestPermission();

  if (authorizationStatus === messaging.AuthorizationStatus.AUTHORIZED) {
    console.log('User has notification permissions enabled.');
  } else if (authorizationStatus === messaging.AuthorizationStatus.PROVISIONAL) {
    console.log('User has provisional notification permissions.');
  } else {
    console.log('User has notification permissions disabled');
  }
}

The value returned is a number value, which can be mapped to one of the following values from messaging.AuthorizationStatus:

  • -1 = messaging.AuthorizationStatus.NOT_DETERMINED: Permission has not yet been requested for your application.
  • 0 = messaging.AuthorizationStatus.DENIED: The user has denied notification permissions.
  • 1 = messaging.AuthorizationStatus.AUTHORIZED: The user has accept the permission & it is enabled.
  • 2 = messaging.AuthorizationStatus.PROVISIONAL: Provisional authorization has been granted.

To help improve the chances of the user granting your app permission, it is recommended that permission is requested at a time which makes sense during the flow of your application (e.g. starting a new chat), where the user would expect to receive such notifications.

It is also possible to fetch the current permission status without requesting permission, by calling the hasPermission API instead.

Provisional authorization

Devices on iOS 12+ can use provisional authorization. This type of permission system allows for notification permission to be instantly granted without displaying a dialog to your user. The permission allows notifications to be displayed quietly;

  • meaning they're only visible within the device notification center.

To enable provisional notifications, pass an object to the requestPermission method, with the provisional key set to true:

await messaging().requestPermission({
  provisional: true,
});

Users can then choose a permission option via the notification itself, and select whether they can continue to display quietly, display prominently or not at all.

Handle button for in-app notifications settings

Devices on iOS 12+ can provide a button in iOS Notifications Settings (at OS level: Settings -> [App name] -> Notifications) to redirect users to in-app notifications settings.

  • Request providesAppNotificationSettings permissions:
await messaging().requestPermission({ providesAppNotificationSettings: true });
  • Handle interaction when app is in background state (eg: with MMKV or Recoil):
// index.js
import { AppRegistry } from 'react-native'
import messaging from '@react-native-firebase/messaging'

...

messaging().setOpenSettingsForNotificationsHandler(async () => {
    MMKV.setBool(openSettingsForNotifications, true)
})

...

AppRegistry.registerComponent(appName, () => App)
// App.tsx

const App = () => {
  const [openSettingsForNotifications] = useMMKVStorage('openSettingsForNotifications', MMKV, false)

  useEffect(() => {
    if (openSettingsForNotifications) {
      navigate('NotificationsSettingsScreen')
    }
  }, [openSettingsForNotifications])

  ...
}
  • Handle interaction when app is in quit state:
// App.tsx

const App = () => {
  useEffect(() => {
        messaging()
            .getDidOpenSettingsForNotification()
            .then(async didOpenSettingsForNotification => {
                if (didOpenSettingsForNotification) {
                    navigate('NotificationsSettingsScreen')
                }
            })
  }, [])

    ...
}