Skip to main content
RapidDev - Software Development Agency
firebase-tutorial

How to Handle Firebase Cloud Messaging in React Native

To handle Firebase Cloud Messaging in React Native, install @react-native-firebase/messaging, configure iOS APNs certificates and Android notification channels, request notification permissions, retrieve the FCM token with getToken(), and set up foreground and background message handlers. Use onMessage for foreground notifications and setBackgroundMessageHandler for background delivery. On iOS, upload your APNs key in the Firebase Console for push notifications to work.

What you'll learn

  • How to install and configure @react-native-firebase/messaging for both platforms
  • How to request notification permissions and retrieve the FCM token
  • How to handle messages in the foreground and background
  • How to configure iOS APNs and Android notification channels
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate8 min read20-30 minReact Native 0.72+, @react-native-firebase/messaging v20+, Firebase Blaze plan (recommended)March 2026RapidDev Engineering Team
TL;DR

To handle Firebase Cloud Messaging in React Native, install @react-native-firebase/messaging, configure iOS APNs certificates and Android notification channels, request notification permissions, retrieve the FCM token with getToken(), and set up foreground and background message handlers. Use onMessage for foreground notifications and setBackgroundMessageHandler for background delivery. On iOS, upload your APNs key in the Firebase Console for push notifications to work.

Implementing Firebase Cloud Messaging in React Native

Firebase Cloud Messaging (FCM) enables push notifications for React Native apps on both iOS and Android. This tutorial covers the full setup using the @react-native-firebase/messaging library, from installing native dependencies to handling messages in every app state: foreground, background, and quit. You will configure platform-specific requirements and build a complete notification handling flow.

Prerequisites

  • A React Native project (0.72 or later) with @react-native-firebase/app configured
  • A Firebase project with Cloud Messaging enabled
  • For iOS: an Apple Developer account with APNs key uploaded to Firebase Console
  • For Android: google-services.json added to android/app directory

Step-by-step guide

1

Install the messaging package

Add the @react-native-firebase/messaging package to your React Native project. This package provides the JavaScript API for FCM and the native modules for iOS and Android. After installing, run pod install for iOS to link the native dependencies. On Android, the native module is auto-linked.

typescript
1npm install @react-native-firebase/messaging
2
3# For iOS:
4cd ios && pod install && cd ..
5
6# For Android: auto-linked, no additional steps

Expected result: The messaging package is installed and native dependencies are linked on both platforms.

2

Configure iOS APNs for push notifications

iOS requires Apple Push Notification service (APNs) configuration for FCM to deliver notifications. Go to your Apple Developer account, create an APNs Authentication Key (p8 file) under Certificates, Identifiers & Profiles > Keys. Upload this key in Firebase Console > Project Settings > Cloud Messaging > Apple app configuration. In Xcode, enable Push Notifications and Background Modes (Remote notifications) capabilities for your app target.

typescript
1// In Xcode:
2// 1. Select your target > Signing & Capabilities
3// 2. Click + Capability > Push Notifications
4// 3. Click + Capability > Background Modes > check 'Remote notifications'
5
6// In Firebase Console:
7// 1. Project Settings > Cloud Messaging
8// 2. Under Apple app configuration, click Upload
9// 3. Upload your APNs Authentication Key (.p8 file)
10// 4. Enter the Key ID and Team ID from Apple Developer portal

Expected result: Xcode shows Push Notifications and Remote notifications capabilities enabled. Firebase Console shows the APNs key uploaded.

3

Request notification permissions

On iOS, you must explicitly request permission from the user before showing notifications. On Android 13+, the POST_NOTIFICATIONS permission is also required. Call requestPermission() early in the app lifecycle, ideally during onboarding. Check the returned authorization status to determine if the user granted, denied, or has not decided.

typescript
1import messaging from '@react-native-firebase/messaging'
2
3async function requestNotificationPermission() {
4 const authStatus = await messaging().requestPermission()
5 const enabled =
6 authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
7 authStatus === messaging.AuthorizationStatus.PROVISIONAL
8
9 if (enabled) {
10 console.log('Notification permission granted:', authStatus)
11 } else {
12 console.log('Notification permission denied')
13 }
14
15 return enabled
16}

Expected result: The permission dialog appears on iOS (and Android 13+), and the app receives the user's response.

4

Retrieve and manage the FCM token

The FCM token uniquely identifies this device for receiving push notifications. Retrieve it with getToken() and send it to your server to store alongside the user's account. Listen for token refreshes with onTokenRefresh() because tokens can change when the app is reinstalled or the user clears app data.

typescript
1import messaging from '@react-native-firebase/messaging'
2
3async function getFCMToken() {
4 const token = await messaging().getToken()
5 console.log('FCM Token:', token)
6
7 // Send token to your backend
8 await saveTokenToServer(token)
9 return token
10}
11
12function listenForTokenRefresh() {
13 return messaging().onTokenRefresh(async (newToken) => {
14 console.log('Token refreshed:', newToken)
15 await saveTokenToServer(newToken)
16 })
17}
18
19async function saveTokenToServer(token: string) {
20 // Save to Firestore, your API, etc.
21 // await firestore().collection('users').doc(userId).update({ fcmToken: token })
22}

Expected result: The FCM token is retrieved and stored on your server for sending targeted notifications.

5

Handle foreground messages

When the app is in the foreground, FCM delivers messages silently without showing a notification banner. Use onMessage() to listen for incoming messages and display them yourself, either with a custom in-app banner or by creating a local notification using a library like notifee. The handler receives a RemoteMessage object with notification and data properties.

typescript
1import messaging from '@react-native-firebase/messaging'
2import { useEffect } from 'react'
3
4function useNotificationHandler() {
5 useEffect(() => {
6 const unsubscribe = messaging().onMessage(async (remoteMessage) => {
7 console.log('Foreground message:', remoteMessage)
8
9 // Option 1: Show in-app alert
10 Alert.alert(
11 remoteMessage.notification?.title || 'Notification',
12 remoteMessage.notification?.body || ''
13 )
14
15 // Option 2: Use notifee for a proper notification banner
16 // await notifee.displayNotification({
17 // title: remoteMessage.notification?.title,
18 // body: remoteMessage.notification?.body,
19 // })
20 })
21
22 return unsubscribe
23 }, [])
24}

Expected result: Foreground messages trigger the onMessage callback and can be displayed to the user.

6

Handle background and quit-state messages

For messages received when the app is in the background or has been quit, register a background handler using setBackgroundMessageHandler(). This must be called outside of any React component, typically in your index.js file. On Android, FCM automatically displays a notification from the notification payload. On iOS, the background handler runs as a headless JS task.

typescript
1// index.js (root of your React Native app)
2import { AppRegistry } from 'react-native'
3import messaging from '@react-native-firebase/messaging'
4import App from './App'
5
6// Register the background handler BEFORE AppRegistry.registerComponent
7messaging().setBackgroundMessageHandler(async (remoteMessage) => {
8 console.log('Background message:', remoteMessage)
9
10 // Process the message (update badge, sync data, etc.)
11 // Do NOT try to update UI state here
12})
13
14AppRegistry.registerComponent('MyApp', () => App)

Expected result: Background messages trigger the handler for data processing, and notification payloads automatically display a system notification.

7

Configure Android notification channels

Android 8.0+ requires notification channels for displaying notifications. Create a channel for your app's notifications with the appropriate importance level. Set the channel ID in your FCM message payload's android.notification.channel_id field to route notifications to the correct channel.

typescript
1import notifee, { AndroidImportance } from '@notifee/react-native'
2
3async function createNotificationChannel() {
4 await notifee.createChannel({
5 id: 'default',
6 name: 'Default Notifications',
7 importance: AndroidImportance.HIGH,
8 vibration: true,
9 sound: 'default',
10 })
11}
12
13// Call this on app startup
14createNotificationChannel()
15
16// When sending from server, include the channel:
17// admin.messaging().send({
18// token: userToken,
19// notification: { title: 'Hello', body: 'World' },
20// android: { notification: { channelId: 'default' } },
21// })

Expected result: Notifications appear with the correct importance level and sound on Android devices.

Complete working example

notifications.ts
1import messaging, {
2 FirebaseMessagingTypes,
3} from '@react-native-firebase/messaging'
4import { Alert, Platform } from 'react-native'
5
6export async function requestPermission(): Promise<boolean> {
7 const authStatus = await messaging().requestPermission()
8 return (
9 authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
10 authStatus === messaging.AuthorizationStatus.PROVISIONAL
11 )
12}
13
14export async function getToken(): Promise<string> {
15 if (!messaging().isDeviceRegisteredForRemoteMessages) {
16 await messaging().registerDeviceForRemoteMessages()
17 }
18 return messaging().getToken()
19}
20
21export function onTokenRefresh(
22 callback: (token: string) => void
23): () => void {
24 return messaging().onTokenRefresh(callback)
25}
26
27export function onForegroundMessage(
28 callback: (msg: FirebaseMessagingTypes.RemoteMessage) => void
29): () => void {
30 return messaging().onMessage(callback)
31}
32
33export function setupForegroundAlert(): () => void {
34 return messaging().onMessage(async (remoteMessage) => {
35 Alert.alert(
36 remoteMessage.notification?.title || 'New notification',
37 remoteMessage.notification?.body || ''
38 )
39 })
40}
41
42export async function initializeNotifications(): Promise<void> {
43 const permitted = await requestPermission()
44 if (!permitted) {
45 console.warn('Notification permission denied')
46 return
47 }
48
49 const token = await getToken()
50 console.log('FCM Token:', token)
51 // TODO: Send token to your backend
52
53 onTokenRefresh((newToken) => {
54 console.log('Token refreshed:', newToken)
55 // TODO: Update token on backend
56 })
57}

Common mistakes when handling Firebase Cloud Messaging in React Native

Why it's a problem: Not uploading the APNs key in Firebase Console, causing iOS notifications to silently fail

How to avoid: Go to Firebase Console > Project Settings > Cloud Messaging > Apple app configuration and upload your APNs Authentication Key (.p8 file) from Apple Developer portal.

Why it's a problem: Calling setBackgroundMessageHandler inside a React component instead of in index.js

How to avoid: Register the background handler at the top level of index.js, before AppRegistry.registerComponent. It must be available before any component mounts.

Why it's a problem: Not creating Android notification channels, causing notifications to be silently dropped on Android 8.0+

How to avoid: Create notification channels at app startup using notifee or the Android native API. Set the channel ID in your FCM payload.

Why it's a problem: Forgetting to enable Background Modes > Remote notifications in Xcode, preventing background delivery on iOS

How to avoid: In Xcode, select your target > Signing & Capabilities > add Background Modes and check 'Remote notifications'.

Best practices

  • Request notification permissions during onboarding with context about why notifications are useful, not immediately on app launch
  • Store FCM tokens in your database keyed by user ID and update them on every token refresh
  • Use the @notifee/react-native library alongside FCM for rich foreground notification display
  • Register setBackgroundMessageHandler in index.js before AppRegistry.registerComponent
  • Create Android notification channels at app startup with the appropriate importance level
  • Use APNs Authentication Keys instead of certificates for iOS, as keys do not expire
  • Handle both notification payloads and data-only payloads to support all notification types

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I need to set up push notifications in my React Native app using Firebase Cloud Messaging. Show me the complete setup for both iOS and Android, including requesting permissions, getting the FCM token, and handling messages in foreground, background, and quit states.

Firebase Prompt

Implement FCM push notifications in React Native with @react-native-firebase/messaging. Create a notifications utility module that requests permissions, retrieves and refreshes the FCM token, handles foreground messages with alerts, and registers a background message handler. Include iOS APNs and Android channel configuration.

Frequently asked questions

Why are my iOS notifications not arriving?

The most common cause is a missing APNs key in Firebase Console. Upload your p8 key under Project Settings > Cloud Messaging > Apple app configuration. Also verify Push Notifications and Background Modes capabilities are enabled in Xcode.

How do I send a notification to a specific user?

Store the user's FCM token in your database when they grant permission. On your server, use the Firebase Admin SDK's messaging().send() with the user's token to deliver a targeted notification.

What is the difference between notification and data messages?

Notification messages include a notification payload and are automatically displayed by the system when the app is in the background. Data messages contain only a data payload and are always delivered to your message handler, giving you full control over display.

Can I send notifications from the Firebase Console without writing server code?

Yes, go to Firebase Console > Messaging > Create your first campaign. You can target by topic, segment, or specific FCM tokens. This is useful for marketing notifications but not for transactional or user-triggered notifications.

How do I test push notifications on iOS Simulator?

The iOS Simulator supports push notification testing since Xcode 11.4. Create an APNs payload file and drag it onto the simulator. However, FCM-specific features like topics require a physical device.

Can RapidDev help implement push notifications for a React Native app?

Yes, RapidDev's engineering team can set up FCM for React Native including platform-specific configuration, server-side notification logic, and in-app notification handling.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.