Endurative

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

  1. Go to Firebase Console
  2. Create a new project → Add an Android app.
  3. Enter your app’s package name (fromandroid/app/src/main/AndroidManifest.xml).
  4. Download the google-services.json file → place inside: (android/app/google-services.json)
  5. 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

  1. Firebase Console → Project Settings → Service Accounts.
  2. Generate Admin SDK key → download service-account.json.
  3. 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

  1. Store FCM tokens per user in DB (MongoDB, SQL, etc.).
  2. Update token on login / app start.
  3. Remove invalid tokens when sendMulticast fails.
  4. Use topics for large groups (admin.messaging().subscribeToTopic()).
  5. 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.