Remote Push notifications in React Native for an Android app

Push notifications was originally an iOS concept. Apple has a push notification service called APNS. App that wants receive notifications should register with the APNS. A server component should send notifications to APNS directed towards one or more devices. The app receives the push notification from APNS and does one of the following actions:

  1. Display a notification or short text message
  2. Play a sound
  3. Update the badge in app icon
  4. Allow the user to perform an action

As you can see, push notifications are a powerful feature in iOS.

Android has a similar messaging system based on Firebase Cloud Messaging (FCM). An example notification message is:

{
    "to" : "device-id",
    "notification": {
        "body": "Get some stuff!",
        "title": "Almost free"
    },
    "data" : {
     "name" : "Retweeter app",
     "price": 0.99
   }
}

The notification has some text and accompanying data. In this tutorial, we will build an Android app named Retweeter which makes use of push notifications. Next up, a brief description of the app that we are going to build.

Overview of Retweeter app

While using Twitter, we want to search tweets by a hashtag, for example, React. Some tweets may be interesting and we want to retweet it with a comment. That is what the Retweeter app accomplishes to do. However, Retweeter app has another purpose. To illustrate how push notifications work. Monitoring twitter for a hashtag will be done by server code. We will host it in Amazon Lambda.

The Amazon Lambda service will check for tweets corresponding to a hashtag. It sends out a push notification asking the user to view those tweets. And for the tweets which are interesting, the user has the option to retweet with a message. The retweet will be done using React Native Share API. So, let’s get started building the Retweeter app.

Create React Native app

Create a new react native app.

create-react-native-app Retweeter

Eject it so that iOS and Android folders show up.

cd Retweeter
yarn run eject

Integrate Firebase with the app

Create a new Firebase app. The Firebase app has a notifications section. Enable it. The step-by-step instructions provided by Google is sufficient to integrate Firebase with the app. It involves downloading a JSON file and adding a new plugin to the gradle build file. After firebase notifications is setup, you should be able to send messages to a topic or device using the Firebase console.

Next, install the package: react-native-firebase

yarn add react-native-firebase

Remote push notifications for an app is not easy, mostly due to configuration. The documentation by react-native-firebase explains the detailed instructions to configure the app. I do not want to repeat the steps in the documentation link. At high level, the steps are:

  • Update gradle settings
  • Update gradle build file of the app module

Make sure that that firebase-messaging is included:

compile "com.google.firebase:firebase-messaging:11.0.0"
  • Include Firebase and Messaging package in the MainApplication java file
  • Add more uses-permission to the manifest: RECEIVE_BOOT_COMPLETED and VIBRATE
  • Set launch mode for android app to singleTop
  • Add a few services to the app – MessagingService and InstanceIdService

Honestly, I do not know the reason behind each and every configuration step. Some points to note while doing the above steps:

  • Apply google services plugin to the end of the file. (SO article)
  • The JSON file (google-services.json) should be placed in android/app folder.
  • Issue with metro-bundler packaging. (Git issue)

Testing the integration

Launch the app in the device using react-native run-android. Add the following code to componentDidMount to get FCM registration token.

componentDidMount() {
    firebase.messaging().getToken()
    .then((token) => {
        console.warn('Device FCM Token: ', token);
    });
  }

To get the firebase registration token, get the logs using react-native log-android.

Send a message using Firebase messaging console.

Message Text: Hello world
Delivery Date: Send now
Target Type: Single Device
FCM registration token: Taken from the logs as explained above

When you send the message, you should see a notification pop in your device. The app must be in background state to receive the message.

Building a Lambda service

AWS Lambda service allows to run server code within AWS compute. For our Retweeter app, we need a server which searches tweets by a hashtag every hour. This is not a tutorial on building Lambda functions. It is more of a tutorial to do a React native app. Please read more about Lambdas on your own. For our tutorial, we will create a deployment package (zip file) containing an index.js and node_modules folder.

The lambda function uses two packages – twit and moment. These packages and the dependent packages go to the node_modules folder.

npm install twit
npm install moment

The index.js file contains the handler for our lambda function.

const Twit = require('twit');
const moment = require('moment');

const bot = new Twit({
    consumer_key: '',
    consumer_secret: '',
    access_token: '',
    access_token_secret: '',
    timeout_ms: 60000
});

exports.handler = (event, context, callback) => {
    bot.get('search/tweets', { q: event.query, count: 10 }, function(err, data) {
        const results = [];
        const oneHourAgo = moment().subtract(1, 'hours');
        data.statuses.forEach(function (status) {
            if (moment(status.created_at).isAfter(oneHourAgo)) {
                console.log(status.user.screen_name, status.text, '\n');
                results.push({
                    name: status.user.screen_name,
                    text: status.text
                });
            }
        });
        callback(null, results);
    });
};

For getting the tweets tweeted in the last one hour, we get the last 10 tweets. Then we check for created_at property to check the tweet time. If it is within the last one hour, we pick the tweet for display.

To get the above lambda to work, we need a Twitter app. After creating a new Twitter app (at twitter.com), the consumer key and secret of the app should be passed to the Twit constructor as shown above.

Assuming that you have by now understood Lambda (by reading about it), you should be able to upload the deployment package, and test the lambda. The result of our test execution should like the below.

Next up

Working with AWS Lambda was not as easy as I thought. So, I will write Part 2 of the article, soon. For now, Part 1 of the article shows how to:

  1. Integrate Firebase messaging into a React native app
  2. Test push notifications from Firebase console
  3. Build a Lambda function which monitors tweets by hash tag

Tutorial Series

Part 1: Sending Remote notifications using Firebase console

Part 2: Sending Remote notifications using AWS Lambda

Part 3: Displaying data from push notifications

Related Posts

One thought on “Remote Push notifications in React Native for an Android app

  1. I didn’t know that the app should be in the background, I almost thought it’s not working. Thank you very much

Leave a Reply

Your email address will not be published.