How to Implement React Native Push Notifications with Firebase

...
Angela Stringfellow
Reading Time: 8 min

Developing mobile and web applications from scratch is an arduous process. Today, developers need not build applications from square one. Open-source packages and code functionalities are available to use. Cloud service providers also have platforms that help to create and host applications in a short time.

Why Firebase?

Firebase is an application development platform from Google. It helps to create application backends quickly, offering a host of built-in features and functionalities that can be integrated readily. Some of the features available with Firebase are analytics, remote configurations, social logins, performance monitoring, email authentication, ad-mob, and cloud messaging.

Messaging features can enhance user engagement. Firebase has a reliable notification integration service to implement push notifications without much hassle.

Firebase Cloud Messaging (FCM) is a messaging solution that can be implemented simultaneously across different platforms. It supports iOS, Android, web, Unity, and C++ setups. FCM can be used to send notification messages or data messages to users. It also can segment users and send different messages to unique user groups. Toast messages and other acknowledgment notifications can also be implemented quickly with Firebase.

The messages can be triggered manually with the help of CRON jobs or based on user interaction using cloud functions. The two components needed to send and receive messages using FCM are:

  1. An application server or cloud functions environment for Firebase to send messages.
  2. A platform-specific client application to receive messages with components for each platform.

Push Notifications: React Native + FCM

React Native is a library maintained by Facebook that can be used to build front-end applications across different platforms. Firebase is a backend-as-a-service solution from Google. These tools can be combined to build a cross-platform application. Below, we’ll discuss how to integrate push notifications in React applications using FCM.

Step 1: Create a New Firebase Project

Go to the Firebase console to create a new project. Follow the prompts and modify them according to your needs. A new Firebase project can be initiated with three simple steps illustrated in the Firebase screenshots below.

Screenshot of Firebase welcome screen
Firebase welcome screen

Click on create a project.

Screenshot of creating a project in Firebase
Name your project in Firebase

Choose a name for your project, accept the Firebase terms, and click continue.

Screenshot of enabling Google Analytics in Firebase
Google Analytics for your Firebase project

In the second step, you can choose to enable or disable Google Analytics for the project.

Screenshot of configuring Google Analytics in Firebase
Configuring Google Analytics in Firebase

The final step is to select a Google Analytics account to be linked with the project, select settings, and accept the terms. Then, click ‘create project.’

Step 2: Create React Native App

Create a new React Native app according to the React documentation.

$ react-native init pushNotifExample

You can run the Android application with the following code snippet:

$ react-native run-android

Step 3: Push Notification Dependency

Multiple packages can be used to add push notification dependency to your React application. react-native-firebase is a popular package that can add all Firebase functionalities to React applications. Here, we use the package react-native-push-notification that only deals with the push notification functionality. You can get the package using node package manager/yarn with the following snippet (from GitHub):

For npm:

$ npm install --save react-native-push-notification

For yarn:

yarn add react-native-push-notification

Step 4: Register Your Application

In the Firebase dashboard, register your Android and/or iOS application. In this example, we will deal with only implementing push notifications for Android apps.

Screenshot of registering an app in Firebase
Register your app in Firebase

Register the Android application with a name.

Screenshot of downloading the config file from Firebase
Download the config file in Firebase

Download the google-services.json file and place it in the root directory of your application module.

Use the following code from the Firebase documentation to the project level build.gradle (<project>/build.gradle):

buildscript {
repositories {
// Check that you have the following line (if not, add it):
google()  // Google's Maven repository
}
dependencies {
...
// Add this line
classpath 'com.google.gms:google-services:4.3.8'
}
}
allprojects {
...
repositories {
// Check that you have the following line (if not, add it):
google()  // Google's Maven repository
...
}
}

Also create the application level build.gradle (<project>/<app-module>/build.gradle) with this code snippet from the Firebase documentation:

apply plugin: 'com.android.application'
// Add this line
apply plugin: 'com.google.gms.google-services'
dependencies {
// Import the Firebase BoM
implementation platform('com.google.firebase:firebase-bom:28.2.1')
// Add the dependencies for the desired Firebase products
// https://firebase.google.com/docs/android/setup#available-libraries
}

Add the following code to AndroidManifest.xml (from GitHub):

<uses-permission android:name="android.permission.WAKE_LOCK" />
<permission
android:name="${applicationId}.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application .......>
<meta-data  android:name="com.dieam.reactnativepushnotification.notification_channel_name"
android:value="YOUR NOTIFICATION CHANNEL NAME"/>
<meta-data  android:name="com.dieam.reactnativepushnotification.notification_channel_description"
android:value="YOUR NOTIFICATION CHANNEL DESCRIPTION"/>
<meta-data  android:name="com.dieam.reactnativepushnotification.notification_color"
android:resource="@android:color/white"/>
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="${applicationId}" />
</intent-filter>
</receiver>
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" />
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationRegistrationService"/>
<service
android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
... </application>

Sync the code.

Step 5: Implement Push Functionality

Use the following code (from GitHub) to call PushNotification.configure at the start of the app. It needs to be written in a separate JS file and imported to App.js.

import React, {Component} from "react";
import PushNotification from "react-native-push-notification";
// var PushNotification = require("react-native-push-notification");
export default class PushController extends Component{
componentDidMount(){
PushNotification.configure({
// (optional) Called when Token is generated (iOS and Android)
onRegister: function(token) {
console.log("TOKEN:", token);
},
// (required) Called when a remote or local notification is opened or received
onNotification: function(notification) {
console.log("NOTIFICATION:", notification);
// process the notification here
// required on iOS only
notification.finish(PushNotificationIOS.FetchResult.NoData);
},
// Android only
senderID: "1090501687137",
// iOS only
permissions: {
alert: true,
badge: true,
sound: true
},
popInitialNotification: true,
requestPermissions: true
});
}
render(){
return null;
}
}

The content of the App.js file looks like this:

import React, { Fragment } from 'react';
import PushController from './PushController';
import { SafeAreaView, StyleSheet, ScrollView, View, Text, StatusBar, FlatList} from 'react-native';
import {Header, LearnMoreLinks, Colors, DebugInstructions, ReloadInstructions } from 'react-native/Libraries/NewAppScreen';
// Dummy data for list, we'll replace this with data received from push
let pushData = [
{
title: "First push",
message: "First push message"
},
{
title: "Second push",
message: "Second push message"
}
]
_renderItem = ({ item }) => (
<View key={item.title}>
<Text style={styles.title}>{item.title}</Text>
<Text style={styles.message}>{item.message}</Text>
</View>
);
const App = () => {
return (
<Fragment>
<StatusBar barStyle="dark-content" />
<SafeAreaView>
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={styles.scrollView}>
<Header />
<View style={styles.listHeader}>
<Text>Push Notifications</Text>
</View>
<View style={styles.body}>
<FlatList
data={pushData}
renderItem={(item ) => this._renderItem(item)}
keyExtractor={(item ) => item.title}
/>
{/* <LearnMoreLinks /> */}
</View>
</ScrollView>
</SafeAreaView>
<PushController/>
</Fragment>
);
};
const styles = StyleSheet.create({
scrollView: {backgroundColor: Colors.lighter,},
listHeader:{ backgroundColor: '#eee', color: "#222", height: 44, padding: 12},
title:{fontSize: 18, fontWeight: 'bold', paddingTop: 10},
message:{ fontSize: 14, paddingBottom: 15, borderBottomColor: "#ccc", borderBottomWidth: 1},
engine: { position: 'absolute', right: 0,},
body: { backgroundColor: Colors.white, paddingHorizontal: 20, paddingVertical: 10, },
sectionContainer: { marginTop: 32, paddingHorizontal: 24, },
sectionTitle: { fontSize: 24, fontWeight: '600', color: Colors.black},
sectionDescription: { marginTop: 8, fontSize: 18, fontWeight: '400', color: Colors.dark,},
highlight: { fontWeight: '700'},
footer: { color: Colors.dark, fontSize: 12, fontWeight: '600', padding: 4, paddingRight: 12, textAlign: 'right',},
});
export default App;
import React, { Fragment } from 'react';
import PushController from './PushController';
import { SafeAreaView, StyleSheet, ScrollView, View, Text, StatusBar, FlatList} from 'react-native';
import {Header, LearnMoreLinks, Colors, DebugInstructions, ReloadInstructions } from 'react-native/Libraries/NewAppScreen';
// Dummy data for list, we'll replace this with data received from push
let pushData = [
{
title: "First push",
message: "First push message"
},
{
title: "Second push",
message: "Second push message"
}
]
_renderItem = ({ item }) => (
<View key={item.title}>
<Text style={styles.title}>{item.title}</Text>
<Text style={styles.message}>{item.message}</Text>
</View>
);
const App = () => {
return (
<Fragment>
<StatusBar barStyle="dark-content" />
<SafeAreaView>
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={styles.scrollView}>
<Header />
<View style={styles.listHeader}>
<Text>Push Notifications</Text>
</View>
<View style={styles.body}>
<FlatList
data={pushData}
renderItem={(item ) => this._renderItem(item)}
keyExtractor={(item ) => item.title}
/>
{/* <LearnMoreLinks /> */}
</View>
</ScrollView>
</SafeAreaView>
<PushController/>
</Fragment>
);
};
const styles = StyleSheet.create({
scrollView: {backgroundColor: Colors.lighter,},
listHeader:{ backgroundColor: '#eee', color: "#222", height: 44, padding: 12},
title:{fontSize: 18, fontWeight: 'bold', paddingTop: 10},
message:{ fontSize: 14, paddingBottom: 15, borderBottomColor: "#ccc", borderBottomWidth: 1},
engine: { position: 'absolute', right: 0,},
body: { backgroundColor: Colors.white, paddingHorizontal: 20, paddingVertical: 10, },
sectionContainer: { marginTop: 32, paddingHorizontal: 24, },
sectionTitle: { fontSize: 24, fontWeight: '600', color: Colors.black},
sectionDescription: { marginTop: 8, fontSize: 18, fontWeight: '400', color: Colors.dark,},
highlight: { fontWeight: '700'},
footer: { color: Colors.dark, fontSize: 12, fontWeight: '600', padding: 4, paddingRight: 12, textAlign: 'right',},
});
export default App;

The Sender ID and other authentication details can be accessed in the Cloud Messaging section under the project settings.

Screenshot of project settings page in Firebase
Project settings in Firebase

Step 6: Run the Android App

You can run the Android application built in the previous steps with the following code snippet:

$ react-native run-android

Step 7: Send Push Notifications from FCM

Go to the FCM dashboard to send messages. It is in the Engage>Cloud Messaging section.

Screenshot of Cloud Messaging in Firebase
Cloud Messaging in Firebase

Follow the prompts to compose and select targets for the push notification.

Screenshot of selecting targets for push notifications in Firebase
Selecting targets for your push notification in Firebase

Select the targets you need.

Screenshot of scheduling push notifications in Firebase
Scheduling push notifications in Firebase

You can decide to send the message now or schedule it for another time.

Screenshot of additional push notifications in Firebase
Additional push notification settings in Firebase

Additional options can be modified according to your requirements. Then, click the review button. Click the publish button in the following popup to send the message according to the settings you provided.

Screenshot of reviewing and publishing push notifications in Firebase
Review and publish your push notification in Firebase

The push notification will be sent on schedule to the application according to the targeting criteria. CRON jobs and cloud functions can be used for advanced push notification functionalities.

What Next?

After implementing push notifications, engage users more by providing an option to access the notifications using an inbox. While creating the push notification using FCM, you can set when the message will expire. An inbox offers a safe place for the message to reside where users can access them anytime. You can use MagicBell to implement customized inbox functionality in your application in a few minutes!

MagicBell - Notification Inbox

Keep Reading

Here are a few related articles!

Get started

Schedule a Demo.

Get a demo and see how you can add MagicBell's notification inbox to your product within an hour.

Schedule a Demo