React Native Firebase integration for Firebase Cloud Messaging (FCM) providing cross-platform push notification capabilities
—
Apple Push Notification service (APNs) integration and iOS-specific messaging features. These capabilities provide deep integration with iOS notification system and platform-specific functionality.
Apple Push Notification service token management for direct APNs integration alongside FCM.
/**
* Get the APNs token for the device (iOS only)
* @returns Promise resolving to APNs token string or null if unavailable
*/
function getAPNSToken(): Promise<string | null>;
/**
* Set the APNs token manually (iOS only)
* @param token - Hexadecimal string representing APNs token
* @param type - Token type: 'prod', 'sandbox', or 'unknown' (optional)
* @returns Promise that resolves when token is set
*/
function setAPNSToken(token: string, type?: 'prod' | 'sandbox' | 'unknown'): Promise<void>;Usage Examples:
import messaging from '@react-native-firebase/messaging';
import { Platform } from 'react-native';
if (Platform.OS === 'ios') {
// Get current APNs token
const apnsToken = await messaging().getAPNSToken();
if (apnsToken) {
console.log('APNs Token:', apnsToken);
// Send token to your server for direct APNs messaging
await sendApnsTokenToServer(apnsToken);
} else {
console.log('APNs token not available');
}
// Set APNs token manually (if method swizzling is disabled)
const deviceToken = await getDeviceTokenFromDelegate();
await messaging().setAPNSToken(deviceToken, 'prod');
}
// Modular API
import { getMessaging, getAPNSToken, setAPNSToken } from '@react-native-firebase/messaging';
const messagingInstance = getMessaging();
if (Platform.OS === 'ios') {
const apnsToken = await getAPNSToken(messagingInstance);
await setAPNSToken(messagingInstance, apnsToken, 'prod');
}Handle when users tap the notification settings link in iOS Settings app.
/**
* Set handler for when notification settings link is opened (iOS 12+)
* @param handler - Function called when settings link is tapped
* @returns void
*/
function setOpenSettingsForNotificationsHandler(handler: (message: RemoteMessage) => any): void;
/**
* Check if app was opened from notification settings (iOS 12+)
* @returns Promise resolving to boolean indicating if opened from settings
*/
function getDidOpenSettingsForNotification(): Promise<boolean>;Usage Examples:
import messaging from '@react-native-firebase/messaging';
import { Platform } from 'react-native';
if (Platform.OS === 'ios') {
// Set handler for settings link (call outside React components)
messaging().setOpenSettingsForNotificationsHandler(remoteMessage => {
console.log('User opened notification settings:', remoteMessage);
// Navigate to in-app notification settings
navigateToNotificationSettings();
});
// Check if app was opened from settings
const openedFromSettings = await messaging().getDidOpenSettingsForNotification();
if (openedFromSettings) {
console.log('App opened from notification settings');
// Show notification settings screen
showNotificationSettingsModal();
}
}
// Modular API
import {
getMessaging,
setOpenSettingsForNotificationsHandler,
getDidOpenSettingsForNotification
} from '@react-native-firebase/messaging';
if (Platform.OS === 'ios') {
const messagingInstance = getMessaging();
setOpenSettingsForNotificationsHandler(messagingInstance, remoteMessage => {
console.log('Settings opened:', remoteMessage);
});
const openedFromSettings = await getDidOpenSettingsForNotification(messagingInstance);
}Configuration options specific to iOS notification behavior and presentation.
/**
* Enable/disable notification delegation to Firebase (iOS only)
* @param enabled - Whether to enable notification delegation
* @returns Promise that resolves when setting is updated
*/
function setNotificationDelegationEnabled(enabled: boolean): Promise<void>;
/**
* Check if notification delegation is enabled (iOS only)
* @returns Boolean indicating delegation status
*/
readonly isNotificationDelegationEnabled: boolean;Usage Examples:
import messaging from '@react-native-firebase/messaging';
import { Platform } from 'react-native';
if (Platform.OS === 'ios') {
// Check current delegation status
const delegationEnabled = messaging().isNotificationDelegationEnabled;
console.log('Delegation enabled:', delegationEnabled);
// Enable notification delegation
await messaging().setNotificationDelegationEnabled(true);
console.log('Notification delegation enabled');
// Disable for custom notification handling
await messaging().setNotificationDelegationEnabled(false);
}
// Modular API
import {
getMessaging,
isNotificationDelegationEnabled,
setNotificationDelegationEnabled
} from '@react-native-firebase/messaging';
if (Platform.OS === 'ios') {
const messagingInstance = getMessaging();
const enabled = isNotificationDelegationEnabled(messagingInstance);
await setNotificationDelegationEnabled(messagingInstance, false);
}When handling messages on iOS, additional properties are available:
interface RemoteMessage {
/** Whether APNs message was configured as background update (iOS) */
contentAvailable?: boolean;
/** Whether APNs mutable-content property was set (iOS) */
mutableContent?: boolean;
/** iOS category for notification actions (iOS) */
category?: string;
/** iOS thread identifier for notification grouping (iOS) */
threadId?: string;
}
interface Notification {
ios?: {
/** Notification subtitle (iOS) */
subtitle?: string;
/** Localization key for subtitle (iOS) */
subtitleLocKey?: string;
/** Localization arguments for subtitle (iOS) */
subtitleLocArgs?: string[];
/** Badge number to display on app icon (iOS) */
badge?: string;
/** Sound file name or critical sound configuration (iOS) */
sound?: string | NotificationIOSCriticalSound;
};
}
interface NotificationIOSCriticalSound {
/** Enable critical alert flag */
critical?: boolean;
/** Sound file name */
name: string;
/** Volume between 0.0 and 1.0 */
volume?: number;
}Detailed iOS notification permission options:
interface IOSPermissions {
/** Display alerts (default: true) */
alert?: boolean;
/** Siri announcement over AirPods (iOS 13+, default: false) */
announcement?: boolean;
/** Update app badge (default: true) */
badge?: boolean;
/** Critical alerts (default: false) */
criticalAlert?: boolean;
/** CarPlay notifications (default: true) */
carPlay?: boolean;
/** Provisional authorization (iOS 12+, default: false) */
provisional?: boolean;
/** Play notification sounds (default: true) */
sound?: boolean;
/** Show notification settings button (iOS 12+, default: false) */
providesAppNotificationSettings?: boolean;
}import messaging from '@react-native-firebase/messaging';
import { Platform } from 'react-native';
async function setupiOSMessaging() {
if (Platform.OS !== 'ios') return;
const messagingInstance = messaging();
// Request permissions with iOS-specific options
const authStatus = await messagingInstance.requestPermission({
alert: true,
badge: true,
sound: true,
provisional: true, // iOS 12+
providesAppNotificationSettings: true, // iOS 12+
criticalAlert: false, // Requires special entitlement
announcement: false, // iOS 13+
carPlay: true,
});
if (authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
authStatus === messaging.AuthorizationStatus.PROVISIONAL) {
// Register for remote notifications
await messagingInstance.registerDeviceForRemoteMessages();
// Get tokens
const fcmToken = await messagingInstance.getToken();
const apnsToken = await messagingInstance.getAPNSToken();
console.log('FCM Token:', fcmToken);
console.log('APNs Token:', apnsToken);
// Send tokens to server
await updateServerTokens({ fcmToken, apnsToken });
return { fcmToken, apnsToken };
}
return null;
}
// Settings handler setup (outside components)
messaging().setOpenSettingsForNotificationsHandler(remoteMessage => {
console.log('User opened notification settings');
// Handle settings navigation
});import messaging from '@react-native-firebase/messaging';
import { Platform } from 'react-native';
// Background message handler (iOS specific considerations)
messaging().setBackgroundMessageHandler(async remoteMessage => {
console.log('Background message on iOS:', remoteMessage);
if (Platform.OS === 'ios') {
// iOS has strict background processing limits
try {
// Perform only essential background tasks
await quickBackgroundTask(remoteMessage);
// Signal completion for iOS background processing
// This is handled automatically by the library
} catch (error) {
console.error('iOS background processing error:', error);
}
}
});// iOS notification categories for interactive notifications
import messaging from '@react-native-firebase/messaging';
import { Platform } from 'react-native';
if (Platform.OS === 'ios') {
// Handle category-based notifications
messaging().onMessage(async remoteMessage => {
if (remoteMessage.category) {
switch (remoteMessage.category) {
case 'MESSAGE_CATEGORY':
await handleMessageNotification(remoteMessage);
break;
case 'REMINDER_CATEGORY':
await handleReminderNotification(remoteMessage);
break;
default:
await handleDefaultNotification(remoteMessage);
}
}
});
}providesAppNotificationSettings for better UXthreadId for notification organizationCommon iOS-specific debugging approaches:
import messaging from '@react-native-firebase/messaging';
import { Platform } from 'react-native';
if (__DEV__ && Platform.OS === 'ios') {
// Debug iOS messaging setup
console.log('iOS Messaging Debug Info:');
console.log('Auto Init Enabled:', messaging().isAutoInitEnabled);
console.log('Device Registered:', messaging().isDeviceRegisteredForRemoteMessages);
console.log('Delegation Enabled:', messaging().isNotificationDelegationEnabled);
// Check initial state
messaging().getDidOpenSettingsForNotification().then(opened => {
console.log('Opened from settings:', opened);
});
messaging().getIsHeadless().then(headless => {
console.log('Is headless:', headless);
});
}Install with Tessl CLI
npx tessl i tessl/npm-react-native-firebase--messaging