August 18, 2019
We will use react-native-firebase
to add push notification in our react-native app and hopefully save your time implementing it.
Let's get started.
Let's create a React Native Project to start implementing Push Notification service. I'm using react-native@0.60.4 which is the latest at the time of writing this article. Go to the terminal and run this command.
react-native init pushNotification
You can replace pushNotification
with the project name of your choice.
Let's create an application on the firebase console to use the Firebase SDK. Go here and create an application.
com.pushnotification
in our case).google-services.json
and paste it inside /pushnotification/android/app/
. Make sure the location is correct.dependencies {
classpath("com.android.tools.build:gradle:3.4.1")
classpath 'com.google.gms:google-services:4.3.0' //Add this line
}
dependendies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "com.facebook.react:react-native:+"
implementation 'com.google.firebase:firebase-core:17.0.1' // Add this line
implementation 'com.google.firebase:firebase-messaging:19.0.1' // Add this line
if (enableHermes) {
def hermesPath = "../../node_modules/hermesvm/android/";
debugImplementation files(hermesPath + "hermes-debug.aar")
releaseImplementation files(hermesPath + "hermes-release.aar")
} else {
implementation jscFlavor
}
}
//Add to the bottom of the file
apply plugin: 'com.google.gms.google-services'
Please use the latest firebase dependency available. You can also add it from Android Studio by going to:
File -> Project Structure -> Dependencies
Go to your project root directory and run this command.
npm install react-native-firebase --save
(Optional) Link the module if your react-native version is less than 0.60.
react-native link react-native-firebase
React Native version (>0.60) supports autolinking.
Follow the Manual Linking guide if you're having issues with linking react-native-firebase
or you're using an earlier version of React Native.
Check out the official docs for updated method.
react-native-firebase
to App-level build.gradle
dependencies {
// ...
implementation project(':react-native-firebase') // Add this line
}
settings.gradle
//Add these lines
include ':react-native-firebase'
project(':react-native-firebase').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-firebase/android')
MainApplication.java
import...
import io.invertase.firebase.RNFirebasePackage; // import core package
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new RNFirebasePackage(), // Add this line
);
}
We have to include other modules as the RNFirebasePackage
we imported earlier provides the core features only.
android/app/build.gradle
file:dependencies {
// ...
implementation 'com.google.firebase:firebase-messaging:19.0.1'
}
MainApplication.java
:import...
// import these two packages
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() // Add this line
new RNFirebaseNotificationsPackage() // Add this line
);
}
Check out official docs for updated method.
Now that we have added all the required libraries hence we should be able to receive a notification. Let's test it out but first make sure your app is in background.
I hope you're able to get a test notification on your device. Let's move on to next section.
This part involves three steps: -
We need to ensure that user has granted required permissions so that we can receive Notifications:
import firebase from 'react-native-firebase';
componentDidMount()
. If permission hasn't been granted then ask for permission in askPermission()
otherwise fetch the token
.async componentDidMount(){
const granted = await firebase.messaging().hasPermission();
if (granted) {
this.fetchToken();
} else {
this.askPermission();
}
}
Request the permissions if not already granted. This step is very important in case for iOS Plateform.
async askPermission(){
try{
await firebase.messaging().requestPermission();
console.log('Permissions allowed');
this.fetchToken();
} catch(error) {
console.log('Permissions denied');
}
}
getToken
from firebase
module and save it in AsyncStorage
. async fetchToken(){
let fcmToken = await AsyncStorage.getItem('fcmToken');
if (!fcmToken) {
fcmToken = await firebase.messaging().getToken();
if (fcmToken) {
await AsyncStorage.setItem('fcmToken', fcmToken);
}
}
}
Firebase Notifications can be of three different types:
A notification will trigger one of these listeners depending on the state of your application:
componentDidMount() {
this.notificationDisplayedListener = firebase.notifications().onNotificationDisplayed((notification) => {
// Process your notification as required
});
this.notificationListener = firebase.notifications().onNotification((notification) => {
// Process your notification as required
});
// App (in background) was opened by a notification
this.notificationOpenedListener = firebase.notifications().onNotificationOpened((notificationOpen) => {
// Get the action triggered by the notification being opened
const action = notificationOpen.action;
// Get information about the notification that was opened
const notification = notificationOpen.notification;
});
// App was opened by a notification
const notificationOpen = await firebase.notifications().getInitialNotification();
if (notificationOpen) {
// Get the action triggered by the notification being opened
const action = notificationOpen.action;
// Get information about the notification that was opened
const notification = notificationOpen.notification;
}
}
componentWillUnmount() {
this.notificationDisplayedListener();
this.notificationListener();
this.notificationOpenedListener();
}
Note: On Android, unfortunately there is no way to access the title and body of an opened remote notification. You can use the data part of the remote notification to supply this information if it's required.
I hope you're able to receive the notification successfully by now.
We will use fcm-node
node module to make our task easier.
You will need two things to trigger a notification.
Follow these simple steps:
3. Go to Cloud Messaging and copy the Server Key from Project credentials
Check out
fetchToken()
function we wrote earlier
Acquire token from AsyncStorage.
let fcmToken = await AsyncStorage.getItem('fcmToken');
Now we are ready to trigger the notification from server.
Run this command in your root server project and install the required module.
$ npm install fcm-node
Sending a Push Notification require 3 simple steps:
var FCM = require('fcm-node');
var serverKey = 'SERVER_KEY'; //put your key here
var fcm = new FCM(serverKey); //pass it to FCM constructor
var message = { //based on message type (single recipient, multicast, topic, et cetera)
to: 'registration_token', // saved in fcmToken variable
collapse_key: 'your_collapse_key', //if you want the notification to be collapsible
notification: {
title: 'Title of your push notification',
body: 'Body of your push notification'
},
data: { //you can send only notification or only data(or include both)
my_key: 'my value',
my_another_key: 'my another value'
}
};
If you want the notification to be collapsible means that the notification may be 'overwritten' in a sense, by another similar message with the same collapse_key value.
Let me explain collapse_key
in more details.
If there is already a message with the same collapse key (and registration token) stored and waiting for delivery, the old message will be discarded and the new message will take its place (that is, the old message will be collapsed by the new one).
However, if the collapse key is not set, both the new and old messages are stored for future delivery.
Go to this link for further reading about the different payload properties of message body: https://firebase.google.com/docs/cloud-messaging/http-server-ref#notification-payload-support
fcm.send(message, function(err, response){
if (err) {
console.log("Something has gone wrong!");
} else {
console.log("Successfully sent with response: ", response);
}
});
That's it. We have successfully completed setting our server to trigger Push Notification.