Push notifications are the single most effective way to bring users back into your app, but if you’ve ever tried to set them up, you know the process can be a nightmare of configuration files and permission hurdles. In this react native firebase push notifications tutorial, I’ll show you exactly how to bridge the gap between your backend and your users’ devices using Firebase Cloud Messaging (FCM).
I’ve implemented this stack in several production apps, and while the documentation is vast, it’s often fragmented. Whether you are building a real-time chat app or a simple reminder tool, getting your notification pipeline right is critical. If you’re also worried about data persistence when the user is offline, you might want to check out my guide on a react native offline first sync strategy to ensure your notifications trigger meaningful data updates.
Prerequisites
- A React Native project (CLI or Expo Prebuild).
- A Firebase account and a project created in the Firebase Console.
- Apple Developer Account (required for iOS push notifications).
- Node.js and Java Development Kit (JDK) installed.
Step 1: Firebase Project Setup
First, head over to the Firebase Console. Create a new project and add both an Android and iOS app to the project. You’ll need your package name (e.g., com.yourname.app) and your iOS Bundle ID.
Download the google-services.json for Android and GoogleService-Info.plist for iOS. Place these files in the root of your /android/app and /ios directories respectively.
Step 2: Installing Dependencies
We will use the industry-standard @react-native-firebase library. Run the following in your terminal:
npm install @react-native-firebase/app @react-native-firebase/messaging
For iOS, don’t forget to install the pods:
cd ios && pod install && cd ..
Step 3: Android Configuration
In your android/build.gradle file, add the google-services classpath:
buildscript {
dependencies {
classpath 'com.google.gms:google-services:4.3.15'
}
}
Then, in android/app/build.gradle, apply the plugin at the bottom:
apply plugin: 'com.google.gms.google-services'
Step 4: iOS Configuration & APNs
iOS is where most developers get stuck. You must enable Push Notifications and Background Modes (Remote notifications) in the Xcode ‘Capabilities’ tab. You also need to upload your .p8 Auth Key from the Apple Developer Portal to the Firebase Console under Project Settings > Cloud Messaging.
As shown in the image below, ensuring the correct capabilities are toggled in Xcode is the most common point of failure for iOS builds.
Step 5: Implementing the Notification Logic
Now, let’s write the code. I recommend creating a separate hook or service to manage notifications so your App.js doesn’t become a mess. Here is a robust implementation:
import messaging from '@react-native-firebase/messaging';
import { Alert, PermissionsAndroid, Platform } from 'react-native';
async function requestUserPermission() {
if (Platform.OS === 'android' && Platform.Version < 33) return true;
const authStatus = await messaging().requestPermission();
const enabled =
authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
authStatus === messaging.AuthorizationStatus.PROVISIONAL;
return enabled;
}
export const setupNotifications = async () => {
const hasPermission = await requestUserPermission();
if (!hasPermission) return;
// Get the device token for the backend
const token = await messaging().getToken();
console.log('FCM Token:', token);
// Handle foreground messages
messaging().onMessage(async remoteMessage => {
Alert.alert('A new FCM message arrived!', JSON.stringify(remoteMessage.notification));
});
};
Step 6: Handling Background and Quit States
To handle notifications when the app is closed or in the background, you must register a background handler in your index.js file:
import messaging from '@react-native-firebase/messaging';
messaging().setBackgroundMessageHandler(async remoteMessage => {
console.log('Message handled in the background!', remoteMessage);
});
Pro Tips for Production
- Token Rotation: Don’t assume the FCM token is permanent. Listen to
onTokenRefreshand update your database accordingly. - Notification Channels: For Android 8.0+, create specific channels (e.g., ‘Orders’, ‘Chat’) so users can mute specific types of alerts without disabling all notifications.
- Payloads: Use
datapayloads instead of justnotificationpayloads if you want to trigger internal app logic without showing a popup.
Troubleshooting Common Issues
If you aren’t receiving notifications, check these three things first:
- Physical Device: Push notifications do not work on the iOS Simulator. Use a real device.
- Incorrect Bundle ID: Ensure the Bundle ID in Firebase matches exactly with the one in Xcode.
- APNs Certificate: Check if your .p8 key has expired or was uploaded to the wrong Firebase project.
What’s Next?
Now that you have the pipeline working, you can integrate more complex features. For instance, if your app involves capturing images for reports, you can use how to use react native vision camera to allow users to snap a photo immediately after clicking a notification. You can also look into integrating Notifee if you need advanced controls like custom sounds or rich media notifications.
Ready to scale? Start by automating your notification triggers using Firebase Cloud Functions to send alerts based on database changes.