CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-native-firebase--messaging

React Native Firebase integration for Firebase Cloud Messaging (FCM) providing cross-platform push notification capabilities

Pending
Overview
Eval results
Files

ios-features.mddocs/

iOS Features

Apple Push Notification service (APNs) integration and iOS-specific messaging features. These capabilities provide deep integration with iOS notification system and platform-specific functionality.

Capabilities

APNs Token Management

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');
}

Notification Settings Handler

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);
}

iOS Notification Configuration

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);
}

iOS-Specific Message Properties

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;
}

iOS Permission Types

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;
}

iOS Integration Patterns

Complete iOS Setup

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
});

iOS Background Processing

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

// 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);
      }
    }
  });
}

iOS Best Practices

  1. Permission Timing: Request permissions at appropriate moments, not immediately on app launch
  2. Provisional Authorization: Use provisional permissions for less intrusive introduction
  3. Settings Integration: Implement providesAppNotificationSettings for better UX
  4. Background Limits: Keep background processing minimal due to iOS restrictions
  5. APNs Integration: Use APNs tokens for direct Apple Push Notification service if needed
  6. Thread Grouping: Use threadId for notification organization
  7. Critical Alerts: Only use with proper entitlements and user understanding
  8. Sound Management: Provide appropriate sound files for different notification types

iOS Debugging

Common 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

docs

android-features.md

index.md

ios-features.md

message-handling.md

permissions-registration.md

token-management.md

topic-management.md

tile.json