React Native Firebase Push Notifications Mobile Development FCM

Learn how to send local and production push notifications in your React Native Application

A comprehensive guide to implementing push notifications in React Native using Firebase Cloud Messaging for both Android and iOS

5 min read

Learn how to send local and production push notifications in your React Native Application

Push notifications are essential for keeping users engaged with your mobile app. From alerting users about new messages to announcing flash sales or order updates, notifications help build stronger connections and boost app usage. In this guide, we’ll show you how to implement push notifications in your React Native app using Firebase Cloud Messaging (FCM) for both Android and iOS.

This step-by-step tutorial covers everything from setting up Firebase to sending test notifications and displaying them with a polished UI. We’ll use a simple chat app example to demonstrate the implementation.

Here’s what we’ll cover:

  1. Firebase Project Setup
  2. Installing Firebase in React Native
  3. Android Configuration
  4. iOS Configuration
  5. Coding Push Notifications
  6. Sending Test Notifications
  7. Displaying Local Notifications with Notifee

Let’s dive in!

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

Head to the Firebase Console and create a new project. Give it a name, enable analytics if desired, and click Create Project.

Next, add apps for both platforms:

  • Android: Enter your app’s package name (found in android/app/build.gradle under applicationId). Download the google-services.json file.
  • iOS: Provide your app’s Bundle ID (found in Xcode or ios/YourApp.xcodeproj/project.pbxproj). Download the GoogleService-Info.plist file.

These files connect your app to Firebase services. Keep them safe for the next steps.

2. Firebase Installation

Install the required Firebase libraries in your React Native project’s root directory:

npm install --save @react-native-firebase/app @react-native-firebase/messaging

Or with Yarn:

yarn add @react-native-firebase/app @react-native-firebase/messaging

Since React Native 0.60+, autolinking handles native module linking, so no additional steps are needed here.

Android Setup

To connect your Android app to Firebase:

  1. Place the google-services.json file in android/app/.
  2. 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
  }
}
  1. Apply the plugin in android/app/build.gradle:
apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'

Note: For Android 13+ (API 33), you’ll need to request the POST_NOTIFICATIONS permission, which we’ll handle in the code later.

Your Android setup is complete! Let’s move to iOS.

iOS Setup

For iOS, follow these steps:

  1. Add the GoogleService-Info.plist file to your Xcode project:
    • Open Xcode, right-click your project in the Project Navigator, and select Add Files to [YourApp].
    • Choose the GoogleService-Info.plist file.
  2. Enable Push Notifications in Xcode:
    • Go to your project’s target > Signing & Capabilities.
    • Click + Capability and add Push Notifications.
    • Optionally, enable Background Modes and check Remote notifications for background handling.
  3. 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;
}
  1. In the Firebase Console, go to Cloud Messaging > Apple app configuration and set up an APNs key or certificate for push notifications.

Important: Test on a physical iOS device, as simulators don’t support FCM notifications.

Usage

FCM sends notifications as data payloads to Android and iOS devices (and Android emulators). We need to handle notifications in three app states:

  • Foreground: App is open and active.
  • Background: App is minimized.
  • Killed: App is closed.

Let’s code the logic to request permissions, handle notifications, and retrieve the FCM token.

Coding Push Notifications

Here’s a complete component that integrates push notifications for a chat app:

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',
  },
});

Key Points:

  • Permissions: The requestUserPermission function checks for notification permissions. On iOS, users may grant provisional permissions for silent notifications.
  • Foreground: The onMessage handler shows an alert for notifications received while the app is open.
  • Background/Killed: The setBackgroundMessageHandler logs notifications for debugging.
  • FCM Token: This unique device identifier is used to send notifications. Securely send it to your backend over HTTPS.

Sending push notification

Let’s test notifications with a Node.js script:

  1. In the Firebase Console, go to Project Settings > Service Accounts and click Generate new private key to download a JSON file.
  2. Create a Node.js project and install firebase-admin:
npm install firebase-admin
  1. Create a script to 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 the script with node your-script.js. For quick tests, use the Firebase Console’s Cloud Messaging section to send a notification without coding.

Local notifications

Using Alert.alert for foreground notifications is fine for testing, but for a native notification UI, we’ll use @notifee/react-native due to its excellent documentation and cross-platform support.

Install Notifee:

npm install @notifee/react-native --save

Update the onMessage handler 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: Notification channels are required for Android 8.0+. Add a ic_notification.png file to android/app/src/main/res/drawable for the notification icon.
  • iOS: The foregroundPresentationOptions ensure notifications appear with banners, sounds, and badges.

Conclusion

You’ve now mastered push notifications in React Native using Firebase and Notifee! From setting up Firebase to displaying native notifications, you’re ready to engage users with timely updates. Stay updated with the Firebase and Notifee documentation, as mobile development evolves quickly.

Experiment with custom notification data or styling to match your app’s vibe. Drop a comment on our site to share how you’re using notifications in your app!