Learn how to send local and production push notifications in your React Native Application
Implementing push notifications in React Native using Firebase Cloud Messaging on Android and iOS
Learn how to send local and production push notifications in your React Native Application
This guide walks through implementing push notifications in React Native with Firebase Cloud Messaging (FCM) on Android and iOS. The example is a chat app.
Sections:
- Firebase Project Setup
- Installing Firebase in React Native
- Android Configuration
- iOS Configuration
- Coding Push Notifications
- Sending Test Notifications
- Displaying Local Notifications with Notifee
Prerequisites
Before starting, ensure you have:
- A React Native project (CLI or Expo).
- Node.js and npm/Yarn installed.
- An Android emulator or physical device, and an iOS physical device (iOS simulators don’t support FCM notifications).
- A Firebase account.
Firebase
1. Firebase Project Setup
In the Firebase Console, create a project. Name it, enable analytics if you want, click Create Project.
Add apps for both platforms:
- Android: Enter your package name (from
android/app/build.gradleunderapplicationId). Downloadgoogle-services.json. - iOS: Enter your Bundle ID (from Xcode or
ios/YourApp.xcodeproj/project.pbxproj). DownloadGoogleService-Info.plist.
Keep both files; you’ll need them next.
2. Firebase Installation
From your project root:
npm install --save @react-native-firebase/app @react-native-firebase/messaging
Or with Yarn:
yarn add @react-native-firebase/app @react-native-firebase/messaging
Autolinking (RN 0.60+) handles the native linking.
Android Setup
- Drop
google-services.jsonintoandroid/app/. - Add the Google Services plugin to
android/build.gradle:
buildscript {
dependencies {
// ... other dependencies
classpath 'com.google.gms:google-services:4.4.2' // Check for the latest version
}
}
- Apply the plugin in
android/app/build.gradle:
apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
On Android 13+ (API 33) you need to request POST_NOTIFICATIONS at runtime. Handled in the code below.
iOS Setup
- Add
GoogleService-Info.plistto the Xcode project: right-click the project in the Navigator, Add Files to [YourApp], pick the plist. - Enable Push Notifications: target > Signing & Capabilities > + Capability > Push Notifications. Add Background Modes > Remote notifications if you want background delivery.
- Initialize Firebase in
ios/YourApp/AppDelegate.m:
#import <Firebase.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FIRApp configure]; // Initialize Firebase
// Other setup code
return YES;
}
- In the Firebase Console, Cloud Messaging > Apple app configuration, upload an APNs key or certificate.
Test on a physical device. iOS simulators don’t deliver FCM notifications.
Usage
FCM delivers payloads to Android and iOS devices (and Android emulators). You handle three app states:
- Foreground: app open and active.
- Background: app minimized.
- Killed: app closed.
Below: request permission, handle notifications, get the FCM token.
Coding Push Notifications
A component wiring it together:
import React, { useEffect } from 'react';
import { SafeAreaView, TouchableOpacity, Text, StyleSheet, Alert } from 'react-native';
import messaging from '@react-native-firebase/messaging';
async function requestUserPermission() {
const authStatus = await messaging().requestPermission();
const enabled =
authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
authStatus === messaging.AuthorizationStatus.PROVISIONAL;
if (!enabled) {
Alert.alert('Permission Denied', 'Please enable notifications in your settings.');
return false;
}
return true;
}
// Handle background and killed states
messaging().setBackgroundMessageHandler(async (remoteMessage) => {
console.log('Background notification:', remoteMessage);
});
export default function NotificationComponent() {
useEffect(() => {
// Handle foreground notifications
const unsubscribe = messaging().onMessage(async (remoteMessage) => {
const { title, body } = remoteMessage.notification;
Alert.alert(title || 'New Message', body || 'You have a new notification!');
});
return () => unsubscribe();
}, []);
const handleEnableNotifications = async () => {
if (!(await requestUserPermission())) {
return;
}
try {
const token = await messaging().getToken();
console.log('FCM Token:', token);
// Send token to your backend (implement sendToApi as needed)
// await sendToApi('/user/notifications', { token });
} catch (error) {
console.error('Error fetching FCM token:', error);
Alert.alert('Error', 'Failed to enable notifications.');
}
};
return (
<SafeAreaView style={styles.container}>
<TouchableOpacity style={styles.btnPrimary} onPress={handleEnableNotifications}>
<Text style={styles.btnPrimaryText}>Enable Notifications</Text>
</TouchableOpacity>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
justifyContent: 'center',
alignItems: 'center',
},
btnPrimary: {
backgroundColor: '#007AFF',
paddingVertical: 12,
paddingHorizontal: 20,
borderRadius: 8,
},
btnPrimaryText: {
color: '#fff',
fontSize: 16,
fontWeight: '600',
},
});
Notes:
requestUserPermissionchecks notification permission. On iOS, users may grant provisional permission for silent notifications.onMessagefires for notifications received while the app is foregrounded.setBackgroundMessageHandlerruns in background/killed states. Logging here is for debugging.- The FCM token identifies the device. Send it to your backend over HTTPS.
Sending push notification
Test with a Node script:
- Firebase Console > Project Settings > Service Accounts > Generate new private key. Save the JSON.
- In a Node project, install
firebase-admin:
npm install firebase-admin
- Send a test notification:
const { initializeApp } = require('firebase-admin/app');
const admin = require('firebase-admin');
const serviceAccount = require('./YOUR_SERVICE_ACCOUNT.json');
initializeApp({
credential: admin.credential.cert(serviceAccount),
});
(async () => {
try {
await admin.messaging().send({
token: 'YOUR_DEVICE_TOKEN', // Replace with your app’s FCM token
notification: {
title: 'New Chat Message',
body: 'Hey, you got a new message!',
},
data: {
screen: 'ChatScreen', // Optional custom data
},
});
console.log('Notification sent successfully!');
} catch (error) {
console.error('Error sending notification:', error);
}
})();
Run with node your-script.js. The Firebase Console’s Cloud Messaging tab also lets you send a test notification without writing code.
Local notifications
Alert.alert works for testing, but for a native notification UI use @notifee/react-native.
Install:
npm install @notifee/react-native --save
Update onMessage to display native notifications:
import notifee, { EventType } from '@notifee/react-native';
import messaging from '@react-native-firebase/messaging';
import { useEffect } from 'react';
useEffect(() => {
// Request Notifee permissions (iOS)
notifee.requestPermission();
// Handle notification taps
notifee.onForegroundEvent(({ type, detail }) => {
if (type === EventType.PRESS) {
console.log('Notification tapped:', detail.notification);
// Navigate to a specific screen (implement as needed)
}
});
const unsubscribe = messaging().onMessage(async (remoteMessage) => {
const { title, body } = remoteMessage.notification;
// Create an Android notification channel
const channelId = await notifee.createChannel({
id: 'default',
name: 'Default Channel',
vibration: true,
sound: 'default',
});
// Display the notification
await notifee.displayNotification({
title: title || 'New Message',
body: body || 'You have a new notification!',
android: {
channelId,
smallIcon: 'ic_notification', // Add to android/app/src/main/res/drawable
pressAction: {
id: 'default',
},
},
ios: {
foregroundPresentationOptions: {
alert: true,
badge: true,
sound: true,
},
},
});
});
return () => unsubscribe();
}, []);
Notes:
- Android 8.0+ requires notification channels. Add
ic_notification.pngtoandroid/app/src/main/res/drawablefor the icon. - On iOS,
foregroundPresentationOptionscontrols whether banners, sounds, and badges show while the app is foregrounded.
Wrap up
That covers FCM setup, sending from a Node script, and rendering native notifications with Notifee. Both the Firebase and Notifee docs are worth reading when you hit edge cases.