Displaying data from push notification

This is the third part of the tutorial series on push notifications for an Android react native app. We are building the Retweeter app. And we are all set to give the finishing touches in this post.

In the first part, we covered how to configure react-native-firebase and get the FCM token. We learnt how to send a push notification manually from the Firebase console.

In the second part, we built a Lambda function which sends out a push notification with a list of tweets. We updated the UI to display the tweets.

In this post, we will learn how to display the tweets from the push notification, build another lambda which sets a hourly trigger and implement the Retweet functionality.

Displaying tweets from push notification

We have already configured push notifications in react native app using react-native-firebase. The code below receives the push notification and displays the tweets within it when the app is active.

// when app is running
firebase.messaging().onMessage((data) => {
    const tweets = JSON.parse(data.message);
    this.setState({
        isQuerySet: true,
        tweets
    });
});

The message property has the tweets. All we need to do for the tweets to be displayed is to set the tweets in the component state. If the push notification activates the app, we use the getInitialNotification.

// when app is started by notification
firebase.messaging().getInitialNotification()
    .then((notification) => {
        const tweets = JSON.parse(notification.message);
        this.setState({
            isQuerySet: true,
            tweets
        });
    });

Lambda to set hourly trigger

So far, we have built a lambda function to retrieve tweets by hashtag and send a push notification. What remains to be done is trigger the lambda on a hourly basis. To set a hourly trigger, we write another lambda.

The two classes that we use from the AWS SDK are CloudWatchEvents and Lambda.

const aws = require('aws-sdk');
const events = new aws.CloudWatchEvents();
const lambda = new aws.Lambda();

To create a new rule in CloudWatch events, we use the putRule method. The method accepts the params – rule name and schedule.

events.putRule({
    Name: RULE_NAME,
    ScheduleExpression: FREQUENCY,
    State: 'ENABLED',
}, function(err, data) {
    if (err) console.log(err);
});

The response (data argument) has the RuleARN property which we will use to add a new permission for the lambda function. The addPermission method accepts the lambda function, rule ARN and permitted action to create a new permission. In our case, the permitted action is to invoke the lambda function (lambda:InvokeFunction) with the rule.

lambda.addPermission({
    FunctionName: FN_NAME,
    StatementId: FN_NAME + '-event',
    Action: 'lambda:InvokeFunction',
    Principal: 'events.amazonaws.com',
    SourceArn: data.RuleArn
}, function(err, data) {
    if (err) console.log(err);
});

The last step is to set a target for the rule using the putTargets method. The CloudWatch event triggers an event based on the schedule. The event is then assigned a payload and is targeted to invoke the lambda. The input payload consists of query (hashtag or search query) and fcm_token (firebase registration token).

const inputEvent = {
    query: event.query,
    fcm_token: event.fcm_token
};

events.putTargets({
    Rule: RULE_NAME,
    Targets: [{
        Id: '1',
        Arn: FN_ARN,
        Input: JSON.stringify(inputEvent)
    }]
}, function(err, data) {
    if (err) console.log(err);
});

Wrap the lambda invocation in an API Gateway. We already have a gateway with an API endpoint of GET /tweets. Create a POST /tweets method. The new method will call our set-rule lambda function with appropriate parameters – query and fcm_token. Finally, we integrate our app with the API gateway.

handleSetPress() {
    fetch(SET_QUERY_API, {
        method: 'POST',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            query: this.state.query,
            fcm_token: this.fcm_token
        })
    })
        .then(response => response.json())
        .then(json => {
            this.setState({
                isQuerySet: true,
                tweets: json
            });
        });
}

It is now time to Retweet.

Retweet

Retweeting is quite simple with react-native-twitter. The other twitter libraries work in NodeJS environment. The react-native-twitter is designed to work with react-native. The twitter client requires four parameters as shown below.

import twitter from 'react-native-twitter';

const client = twitter({
    consumerKey: CONSUMER_KEY,
    consumerSecret: CONSUMER_SECRET,
    accessToken: ACCESS_TOKEN,
    accessTokenSecret: ACCESS_TOKEN_SECRET
});

After the client is created, we do a simple POST operation providing the tweet id which needs to be retweeted. After the retweet, we update the internal state of the tweet to indicate that the tweet has been retweeted.

handleRetweet(id) {
    client.rest.post('statuses/retweet/:id', { id })
        .then(() => {
            let { tweets } = this.state;
            tweets = tweets.slice();
            const index = tweets.findIndex(t => t.id === id);
            if (index !== -1) {
                tweets[index] = {
                    ...tweets[index],
                    retweeted: true
                };
                this.setState({ tweets });
            }
        });
}

The id of the tweet is provided by the Retweet button. Finally, we swap the button component for a text component when the retweet is completed.

{item.retweeted ? (
    <Text>Retweeted</Text>
) : (
        <Button
            title="Retweet"
            onPress={this.handleRetweet.bind(this, item.id)}
        />
    )}

Finally, we have come to the end of the tutorial.

Summary

We have covered a lot of ground in the tutorial. We have done the following steps:

  1. Created a react-native app.
  2. Integrated react-native-firebase with the app.
  3. Send a push notification to the device from firebase console.
  4. Built a lambda function to search tweets by keyword.
  5. Setup an API Gateway for the lambda function.
  6. Created the UI for the app to display tweets.
  7. Built a lambda function to send push notification.
  8. Display tweets from the push notification.
  9. Built a lambda to set hourly trigger.
  10. Retweet a tweet displayed in the UI.

There are a few things that we did not cover.

  1. Login using twitter (OAuth).
  2. Allowing the app to work with multiple users.
  3. Change the keyword for tweets.
  4. Pause or stop receiving push notifications.

I have the code in a Git repo for you to follow along. Hope you found the tutorial useful.

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

Leave a Reply

Your email address will not be published.