React Native Firebase Cloud Messaging (FCM) Push Notification

by Didin J. on Sep 10, 2019 React Native Firebase Cloud Messaging (FCM) Push Notification

A comprehensive step by step tutorial on integrating Firebase Cloud Messaging (FCM) push notification to React Native Mobile Apps

In this tutorial, we will show you how to integrate Firebase Cloud Messaging (FCM) push notification to the React Native Mobile Apps (Android or iOS) using React Native Firebase (react-native-firebase) module. React Native Firebase makes using Firebase with React Native simple. It provides a light-weight layer on-top of the native Firebase SDKs (iOS & Android) whilst mirroring the Firebase Web SDKs API as closely as possible. One of the React Native Firebase Module features is Cloud Messaging or FCM. The first steps of this tutorial almost the same as the previous React Native Firebase tutorial.

Table of Contents:

The following tools, frameworks, and modules are required for this tutorial:

  1. React Native
  2. Node.js (NPM or Yarn)
  3. Firebase Cloud Messaging (FCM)
  4. React Native Firebase library
  5. Android Studio or SDK for Android
  6. XCode for iOS
  7. Terminal (OSX/Linux) or Command Line (Windows)
  8. Text Editor or IDE (We are using Atom)

Before start to the main steps, make sure that you have installed Node.js and can run `npm` in the terminal or command line. To check the existing or installed Node.js environment open the terminal/command line then type this command.

node -v
v10.15.1
npm -v
6.11.2
yarn -v
1.10.1


Setup Google Firebase Cloud Messaging (FCM)

We are using Firebase Cloud Messaging (FCM) because it's a cross-platform messaging solution that lets you reliably deliver messages at no cost. Open your browser then go to Google Firebase Console then log in using your Google account.

React Native Firebase Cloud Messaging (FCM) Push Notification - Console Firebase

From that page, click "+" add project button to create a Google Firebase project then it will be redirected to this page.

React Native Firebase Cloud Messaging (FCM) Push Notification - Create Project 1

After filling the project name text field which our project name is "React Native" then click continue button and it will be redirected to this page.

React Native Firebase Cloud Messaging (FCM) Push Notification - Create Project 2

Scroll down then choose to not add Firebase analytics for now then click Create Project button. Now, you have a Google Firebase Project ready to use.

React Native Firebase Cloud Messaging (FCM) Push Notification - Finished

After click Continue button it will be redirected to this page.

React Native Firebase Cloud Messaging (FCM) Push Notification - Create App

Next, click the iOS button to add a new iOS application.

React Native Firebase Cloud Messaging (FCM) Push Notification - Register App

Fill the iOS bundle ID field (ours: "com.djamware.reactnative") then click the Register App button.

React Native Firebase Cloud Messaging (FCM) Push Notification - Download Google Service

Download the GoogleService-info.plist file then click the Next Button several times to the last steps of the wizard then click the Continue to Console button to finish it. Do the same way for the Android application, so, you will have a configuration google-service.json file. Keep those configuration files for use with the React Native app later.

Next, click the Gear button then choose project settings.

React Native Firebase Cloud Messaging (FCM) Push Notification - API Key

Click the Cloud Messaging tab then it will take to this page.

React Native Firebase Cloud Messaging (FCM) Push Notification - Server Key

Write down the server key to your notepad or text editor. That Firebase server key will use to send the push notification from your server or just using Postman application.


Install React Native CLI and Create App

This time we will use React Native CLI to create a React Native app because the Firebase Cloud Messaging will use natively. To install it, type this command in your App projects folder.

sudo npm install -g react-native-cli

Then create a React Native App using this command from your projects directory.

react-native init ReactNativeFcm

Next, go to the newly created React App folder and run the React Native app to the simulator.

cd ReactNativeFcm && react-native run-ios

When a new terminal window opened, go to the React Native project folder then run the Metro bundler server.

cd ~/Apps/ReactNativeFcm && yarn start

Now, you will see this in the iOS simulator.

React Native Firebase Cloud Messaging (FCM) Push Notification - React Native Welcome

Next, we will change the iOS and Android package name or bundle ID to match the Firebase configuration files. For iOS, open the `ios/ReactNativeFcm.xcworkspace` file using XCode.

React Native Firebase Cloud Messaging (FCM) Push Notification - XCode

Just change the Bundle Identifier (ours: com.djamware.reactnative) and it ready to use with the Firebase Cloud Messaging. For Android a little tricky, first, change the source folders which previously `android/app/src/main/java/com/reactnativefcm` become `android/app/src/main/java/com/djamware/reactnative`.

React Native Firebase Cloud Messaging (FCM) Push Notification - package name

Next, open and edit `android/app/src/main/java/com/djamware/reactnative/MainActivity.java` then this package name.

package com.reactnativefcm;

to

package com.djamware.reactnative;

Do the same way to `android/app/src/main/java/com/djamware/reactnative/MainApplication.java`. Next, open and edit `android/app/src/main/AndroidManifest.xml` then change this line.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.reactnativefcm">

To

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.djamware.reactnative">

Next, open edit `android/app/build.gradle` then change the application ID to the new package.

android {
  ...

  defaultConfig {
      applicationId "com.djamware.reactnative"
      minSdkVersion rootProject.ext.minSdkVersion
      targetSdkVersion rootProject.ext.targetSdkVersion
      versionCode 1
      versionName "1.0"
  }
  ...
}

Next, open and edit `android/app/BUCK` then change the android_build_config and android_resource package name.

android_build_config(
    name = "build_config",
    package = "com.djamware.reactnative",
)

android_resource(
    name = "res",
    package = "com.djamware.reactnative",
    res = "src/main/res",
)

Finally, run this command from the android folder to clean up the Gradle.

./gradlew clean


Install and Configure React Native Firebase

We will use React Native Firebase (RNFirebase) module to access the Google Firebase services. React Native Firebase is a simple Firebase integration for React Native. To install it dependencies just type this command.

npm install --save react-native-firebase

or

yarn add react-native-firebase

Next, link the react-native-firebase to native iOS and Android apps by type this command.

react-native link react-native-firebase

Setup React Native Firebase on Android

Copy the previously downloaded google-services.json to `android/app/` folder.

cp ~/Downloads/google-services.json android/app/

Next, open and edit `android/build.gradle` then add this classpath dependency of Google Services.

dependencies {
    classpath("com.android.tools.build:gradle:3.4.1")
    classpath 'com.google.gms:google-services:4.2.0'
}

Also, add the Google maven repository at repositories block and make orders like this.

repositories {
    google()
    maven {
        url 'https://maven.google.com'
    }
    jcenter()
}

Open and edit `android/app/build.gradle` then add this line to the bottom of the file.

apply plugin: "com.google.gms.google-services"

Add these lines of Firebase implementation to the dependencies.

dependencies {
    ....
    implementation "com.google.android.gms:play-services-base:16.1.0"
    implementation "com.google.firebase:firebase-core:17.0.1"
    implementation "com.google.firebase:firebase-messaging:19.0.1"
    implementation 'me.leolin:ShortcutBadger:1.1.21@aar'
    ....
}

Next, open and edit `android/app/src/main/java/com/djamware/reactnative/MainApplication.java` then add these imports of RNFirebaseMessagingPackage and  RNFirebaseNotificationsPackage.

import io.invertase.firebase.messaging.RNFirebaseMessagingPackage;
import io.invertase.firebase.notifications.RNFirebaseNotificationsPackage;

Add that packages to the list of packages.

@Override
protected List<ReactPackage> getPackages() {
  @SuppressWarnings("UnnecessaryLocalVariable")
  List<ReactPackage> packages = new PackageList(this).getPackages();
  // Packages that cannot be autolinked yet can be added manually here, for example:
  // packages.add(new MyReactNativePackage());
  packages.add(new RNFirebaseMessagingPackage());
  packages.add(new RNFirebaseNotificationsPackage());
  return packages;
}

Next, open and edit `android/app/src/main/AndroidManifest.xml` then add these Android permissions after INTERNET permission.

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />

Add the Firebase MESSAGING_EVENT before the closing of <application> tag.

<application ...>
  ...
  <service android:name="io.invertase.firebase.messaging.RNFirebaseMessagingService">
    <intent-filter>
      <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
  </service>
</application>

Run again this re-link commands from the terminal.

react-native unlink react-native-firebase
react-native link react-native-firebase

Setup React Native Firebase on iOS

To use Firebase Cloud Messaging Push Notification with APNs (Apple Push Notification Service) we have to add the Apple Provisioning Profiles that enabled Push Notification as .P12 file to the Firebase Console under the iOS app. For that, you must have an Apple Developer Account with Enrollment to create App ID, Certificates, and Profiles. If you have the account, you can follow this Guide from the Firebase. After the APP ID, Certificates, and Provisioning Profiles created use the certificates in the XCode signing profile.

Next, open the `ios/ReactNativeFcm.xcworkspace` from the XCode then add the previously downloaded GoogleService-Info.plist to the XCode project name.

React Native Firebase Cloud Messaging (FCM) Push Notification - Add GoogleService-Info.plist

After added to the XCode project will be like this.

React Native Firebase Cloud Messaging (FCM) Push Notification - GoogleService-Info.plist

In the XCode, enable the Capabilities for the remote notification by click on the project name in the left pane then click Capabilities tabs. Find and On the Background Modes then check the Remote notification.

Next, open and edit `Pods/podfile` then add these lines of Firebase Pods.

pod 'Firebase/Core'
pod 'Firebase/Messaging'

Change the Pod path for RNFirebase to be like this.

pod 'RNFirebase', :path => '../node_modules/react-native-firebase/ios'

Or find and match RNFirebase podspec in the node_modules otherwise you will get this error.

[!] No podspec found for `RNFirebase` in `../node_modules/react-native-firebase`

Run this command from the terminal inside the `ios` folder.

cd ios
pod update

Next,  open and edit `ReactNativeFcm/AppDelegate.m` then add these import of the Firebase, React Native Firebase Notifications, and Messaging.

#import <Firebase.h>
#import "RNFirebaseNotifications.h"
#import "RNFirebaseMessaging.h"

At the beginning of the `didFinishLaunchingWithOptions:(NSDictionary *)launchOptions` method add these lines to initialize Firebase and RNFirebaseNotifications.

[FIRApp configure];
[RNFirebaseNotifications configure];

Add a new method to receive RNFirebaseNotifications local notification.

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
  [[RNFirebaseNotifications instance] didReceiveLocalNotification:notification];
}

Add a new method to receive a remote RNFirebaseNotifications.

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo
fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler{
  [[RNFirebaseNotifications instance] didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}

Add a new method to register to the Firebase and get FCM token.

- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
  [[RNFirebaseMessaging instance] didRegisterUserNotificationSettings:notificationSettings];
}


Implementing FCM Push Notification

After everything set up and configured for the Android and iOS (in XCode), now, we have to implement the FCM push notification in React Native side using React Native Firebase module. Just open and edit `App.js` then add or modify these imports of Firebase, React Hooks useEffect, and React Native Alert.

import React, {Fragment,useEffect} from 'react';
import {
  SafeAreaView,
  StyleSheet,
  ScrollView,
  View,
  Text,
  StatusBar,
  Alert
} from 'react-native';
import firebase from 'react-native-firebase';

Implement the use effect function or method that run checkPermission and messageListener functions.

useEffect(() => {
  this.checkPermission();
  this.messageListener();
}, []);

Add a function to check the permissions.

checkPermission = async () => {
  const enabled = await firebase.messaging().hasPermission();
  if (enabled) {
      this.getFcmToken();
  } else {
      this.requestPermission();
  }
}

Add a function to get FCM token from the Firebase and show the token to the React Native Alert.

getFcmToken = async () => {
  const fcmToken = await firebase.messaging().getToken();
  if (fcmToken) {
    console.log(fcmToken);
    this.showAlert('Your Firebase Token is:', fcmToken);
  } else {
    this.showAlert('Failed', 'No token received');
  }
}

Add a function to request new permission to use Firebase Notification services.

requestPermission = async () => {
  try {
    await firebase.messaging().requestPermission();
    // User has authorised
  } catch (error) {
      // User has rejected permissions
  }
}

Add a function to listen to the incoming messages or Push Notification from the Firebase Cloud Messaging (FCM) then show them as an Alert when the App is open.

messageListener = async () => {
  this.notificationListener = firebase.notifications().onNotification((notification) => {
      const { title, body } = notification;
      this.showAlert(title, body);
  });

  this.notificationOpenedListener = firebase.notifications().onNotificationOpened((notificationOpen) => {
      const { title, body } = notificationOpen.notification;
      this.showAlert(title, body);
  });

  const notificationOpen = await firebase.notifications().getInitialNotification();
  if (notificationOpen) {
      const { title, body } = notificationOpen.notification;
      this.showAlert(title, body);
  }

  this.messageListener = firebase.messaging().onMessage((message) => {
    console.log(JSON.stringify(message));
  });
}

Add a function to show an alert with a title and message params.

showAlert = (title, message) => {
  Alert.alert(
    title,
    message,
    [
      {text: 'OK', onPress: () => console.log('OK Pressed')},
    ],
    {cancelable: false},
  );
}


Run and Test React Native Firebase App

To run the whole React Native Firebase App, first, re-link again the React Native to React Native Firebase.

react-native unlink react-native-firebase
react-native link react-native-firebase

Run the React Native app to the Android device using this command. Make sure the Android device connected using USB cable and USB Debugging is enabled so it can be detected using ADB command.

react-native run-ios

The new terminal tab will open then run the Metro Bundler after going to the root of the project folder.

cd ~/Apps/ReactNativeFcm && yarn start

For the iOS, we can open the `ios/ReactNativeFcm.xcworkspace` from the XCode then use the valid provisioning profile signing then run the iOS app from there while the Metro Bundler runs from the terminal.

Next, open the Postman app then change the method to POST and the address to `https://fcm.googleapis.com/fcm/send`. In the headers tab, add Authorization with the value of the Firebase Cloud Messaging Key that previously gets when setup the Firebase. Also, add the Content-Type of `application/json` as the second headers.

React Native Firebase Cloud Messaging (FCM) Push Notification - Postman

In the body tabs, choose the RAW and fill with the JSON like below.

{
    "to" : "cFgZQf_bGtc:APA91bF0xbAObLc1CwyBe8lINHaZ_V2PvmsYJ53URUYT1gQwBcglYIi_fdnnpl7KEkNeWOZgmaTWu-hsFGDT7BNaMsEZl37VybPHSXaU0vKZwMl6HfV8VzZlmluIbHTqxwSD7r8Fmy4i",
    "notification" : {
        "body" : "The first message from the React Native and Firebase",
        "title" : "React Native Firebase",
        "content_available" : true,
        "priority" : "high"
    },
    "data" : {
        "body" : "The first message from the React Native and Firebase",
        "title" : "React Native Firebase",
        "content_available" : true,
        "priority" : "high"
    }
}

You can change the "to" with the received FCM token that showed up in the alert when the React Native app started in the devices. Click the Send button and you will see the push notification in the device like this.

React Native Firebase Cloud Messaging (FCM) Push Notification - Push Notification

That it's, the React Native Firebase Cloud Messaging (FCM) Push Notification. You can find the full source from our GitHub.

That just the basic. If you need more deep learning about React.js, React Native or related you can take the following cheap course:

Thanks!