Firebase Cloud Messaging (FCM) Push Notifications in React Native Android [2025 Guide]
A robust notification system is a must-have for modern React Native apps. In this guide, you’ll learn how to integrate Firebase Cloud Messaging (FCM) with Notifee to handle push notifications, and set up a Node.js backend to send them programmatically.
1. Project Setup
npx @react-native-community/cli@latest init AwesomeProject
cd AwesomeProject
2. Install Dependencies
# Firebase SDK for React Native
npm install @react-native-firebase/app @react-native-firebase/messaging
# Notifee for local notification display
npm install @notifee/react-native
3. Firebase Setup
- Go to Firebase Console
- Create a new project → Add an Android app.
- Enter your app’s package name (fromandroid/app/src/main/AndroidManifest.xml).
- Download the google-services.json file → place inside: (android/app/google-services.json)
- Add Firebase Gradle config:
android/build.gradle
buildscript {
dependencies {
classpath 'com.google.gms:google-services:4.3.15'
}
}
android/app/build.gradle
apply plugin: 'com.google.gms.google-services'
dependencies {
implementation ("com.google.firebase:firebase-messaging")
}
4. App Integration
Request Notification Permission:
// App.js
import notifee, { AuthorizationStatus } from '@notifee/react-native';
import messaging from '@react-native-firebase/messaging';
import { useEffect } from 'react';
async function requestNotificationPermission() {
const settings = await notifee.requestPermission();
if (settings.authorizationStatus >= AuthorizationStatus.AUTHORIZED) {
console.log('Notification permission granted');
} else {
console.log('Permission denied');
}
}
Get FCM Token:
import { getApp } from '@react-native-firebase/app';
import { getMessaging, getToken, setBackgroundMessageHandler } from '@react-native-firebase/messaging';
//Get FCM Token once app starts
async function fetchFCMToken() {
try {
const app = getApp(); // default app
const messaging = getMessaging(app);
const token = await getToken(messaging);
console.log('FCM Token:', token);
} catch (err) {
console.error('Failed to get FCM token:', err);
}
}
fetchFCMToken();
Foreground Message Handler: (App.tsx)
useEffect(() => {
const unsubscribe = messaging().onMessage(async remoteMessage => {
console.log('📩 FCM in foreground:', remoteMessage);
await notifee.displayNotification({
title: remoteMessage.notification?.title || 'Default Title',
body: remoteMessage.notification?.body || 'Default Body',
android: {
channelId: 'default',
},
});
});
return unsubscribe;
}, []);
Background Handler (index.js):
import messaging from '@react-native-firebase/messaging';
import { AppRegistry } from 'react-native';
import App from './App';
import { name as appName } from './app.json';
setBackgroundMessageHandler(getMessaging(), async remoteMessage => {
console.log('📩 Message handled in the background!', remoteMessage);
});
AppRegistry.registerComponent(appName, () => App);
Create Notification Channel (Android):
useEffect(() => {
async function createChannel() {
await notifee.createChannel({
id: 'default',
name: 'Default Channel',
});
}
createChannel();
requestNotificationPermission();
}, []);
5. Backend Setup (Node.js + Firebase Admin)
Install Firebase Admin SDK
mkdir backend && cd backend
npm init -y
npm install express firebase-admin
Service Account Key
- Firebase Console → Project Settings → Service Accounts.
- Generate Admin SDK key → download service-account.json.
- Save it inside your backend project.
Express Server (server.js)
const express = require("express");
const admin = require("firebase-admin");
const serviceAccount = require("./service-account.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
});
const app = express();
app.use(express.json());
app.post("/sendNotification", async (req, res) => {
const { tokens, title, body, data } = req.body;
try {
const message = {
tokens,
notification: { title, body },
data: data || {},
};
const response = await admin.messaging().sendMulticast(message);
console.log("✅ Sent:", response.successCount, "❌ Failed:", response.failureCount);
res.status(200).json(response);
} catch (error) {
console.error("Error:", error);
res.status(500).send("Notification failed");
}
});
app.listen(5000, () => console.log("🚀 Server running on http://localhost:5000"));
6. Testing
Start Backend
node server.js
Send Notification via Postman / Curl
curl -X POST http://localhost:5000/sendNotification \
-H "Content-Type: application/json" \
-d '{
"tokens": ["YOUR_FCM_TOKEN"],
"title": "🔥 Test Push",
"body": "Hello from Backend",
"data": { "customKey": "123" }
}'
If everything is set up, your React Native app will receive and display the push notification both in foreground and background.
6. Production Considerations
- Store FCM tokens per user in DB (MongoDB, SQL, etc.).
- Update token on login / app start.
- Remove invalid tokens when sendMulticast fails.
- Use topics for large groups (admin.messaging().subscribeToTopic()).
- Add retries with exponential backoff for massive scale.
With this setup, you now have a complete pipeline — React Native app → FCM token generation → backend storage → targeted push delivery. Drop a comment below if you run into any issues.