React Native: Integrating Push Notifications using FCM

Recently, I integrated push notifications in my react native app using react-native-firebase. I came across many challenges during the process of integration to successful implementation, so I thought to share steps with everyone here.

Create Application On Console

First create an application on Firebase console. Follow steps in Cloud Messaging Section, add iOS and Android apps as per your requirement.

Cloud Messaging Section — Firebase

Make sure your google-services.json and GoogleService-Info.plist are placed in correct folders.

Correct Placement of Google Services files

Android

Configure gradle files. Please use the latest firebase dependencies available while following this tutorial. You can find official FCM guide here. For your reference, my gradle files are as follows:

App module build gradle snippet
Root build gradle snippet

iOS

  1. In Firebase console, you have to include either APNs Authentication Key or APNs Certificate in Project Settings > Cloud Messaging in order to receive push notifications. Creation of push certificate is out of scope in this tutorial, so here is a nice link for your reference :)
Note: You need two separate push certificates. One for Sandbox Environment (Development Certificate) and other for Production (Distribution Certificate). Both should be uploaded to Firebase Console.

2. Turn on following two capabilities in Xcode. Make sure these are turned on in certificates as well created in step 1.

a) Push Notifications

b) Background Modes - Check only Remote Notifications

Make sure you open <YourProject>.xcworkspace file using Xcode instead of <YourProject>.xcodeproj.

3. Open Podfile and edit its contents as follows:

Podfile contents snippet

If you haven’t setup pods before, please follow guide from here. If you face any error, you can check official FCM guide.


Install Firebase Module

Run following command in root folder of your react project.

npm install --save react-native-firebase

You can link firebase node module with native applications using following command:

react-native link react-native-firebase

Here I will be linking firebase node module with native platforms manually without react-native link, since it avoids mess and incomplete bindings most of the times. Moreover, if you are face any issues after linking, you can confirm steps from below that everything is included correctly in native platforms.

Android Setup

  1. Edit MainApplication.java:
import io.invertase.firebase.RNFirebasePackage;
import io.invertase.firebase.messaging.RNFirebaseMessagingPackage; import io.invertase.firebase.notifications.RNFirebaseNotificationsPackage;
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new RNFirebasePackage(),
new RNFirebaseMessagingPackage(),
new RNFirebaseNotificationsPackage()
);
}

2. Add these lines in settings.gradle

include ':react-native-firebase'                       project(':react-native-firebase').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-firebase/android')

3. In app build gradle, add dependency:

dependencies {
compile(project(':react-native-firebase')) {
transitive = false
}
// ... other dependencies listed
}

Sync gradle. You should be good to go for Android. At this point, we can quickly test notification on Android Device from Firebase Console.

Make sure your application is in background while testing, so that Firebase can automatically deliver to notification tray.

To test on console:

a) Go to Cloud Messaging section on left Pane.

b) Click on Send your first message.

c) Enter text, Select your app in User Segment and click Send Message button. You should be able to receive notification.

iOS Setup

  1. In Project Navigator, right click Libraries > Add Files To <YourProject>. Navigate to <YourProject>/node_modules/react-native-firebase/ios/. Select RNFirebase.xcodeproj and click Add button.
  1. Go to Build Phases. Click on the “+” under “Link Binary With Libraries” to add a new library. Add UserNotifications.framework. This framework is required since iOS 10 for push notifications handling.
  2. Again click “+”, select libRNFirebase.a and add it. If you are unable to find it, clean and build project.
  3. Go to Build Settings, find Header Search Path, double click its value and press “+” button. Add following line there:
$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase

Use “Cmd +Shift + Enter + K” keys to clear cache and then build project. Now firebase dependencies should be recognized by xcode.

4. In AppDelegate:


Receive Push Notifications

Now lets code the most awaited part… Receiving Notifications! 😉

Handling Permissions

Before app can get any notifications, it is crucial to ask permission from user specially in iOS. If user didn’t allow your app to receive notifications, it can never get any unless user explicitly change it from Settings.

Open main component of your React Native app, from where basically routing starts i.e. App.js. Modify file as per the snippets below.

  1. In componentDidMount, we check if user has granted permission to receive push notifications.
  2. If permission hasn’t been granted to our app, request user in requestPermission method. If permission is successfully assigned, proceed towards token fetch, otherwise gracefully ignore the fact.
  3. If token was fetched earlier, it can be retrieved from AsyncStorage. If no token is found, request Firebase and save it in AsyncStorage.

Listening Notifications

We are now ready to listen push notification events. Before proceeding, you should know about different types of notifications supported by Firebase.

  • Notification-only messages: These are display messages that are automatically handled by Firebase SDK. Notifications are thrown to device tray.
  • Notification + optional data messages: These are also handled by Firebase SDK. Only difference here is when user taps on notification, your app receives payload associated with that notification.
  • Data only messages: These types of notifications are handled exclusively by app. No notification is thrown on device tray unless app explicitly does so. In iOS, these types of notifications are also termed as ‘Silent Push Notifications’.

For more details, you can read from here.

Add these lines in App.js.

I hope comments would be enough to explain all scenarios. You should be now able to receive notifications on both platforms.

In iOS, you need to test on Device to receive notifications. iOS Simulator doesn’t support Push Notifications currently.
In Android, if you want to test on emulator, you need to install Google Play Services package.

React-native-firebase is a nice wrapper over Firebase for react native. However, there are few points you should know:

  1. In Android, if you tap on notification when app is killed, this library won’t be able to catch title and body of notification. Therefore these attributes will be undefined in showAlert function. As a solution, you should also send title and body in data payload of notification.
  2. To this date, Silent Push Notifications on iOS are not supported by this library. I have already opened an issue on their repository.
  3. To listen for data message notifications while the app is in background or killed in Android, you need to implement Headless JS functionality. For details, please refer to this link.

Hope this tutorial saves your time and make FCM integration easy in react native. If it helps you in anyway, don’t forget to clap! Thanks :)

References: