Part 2: Push Notifications with Ionic 3

02 June 2017 on Ionic2. 5 minutes

Part 2: Direct Notifications to Individual Devices

In Part 1 of this blog post, we looked at how to configure push notifications on iOS and Android with Ionics Push notification service. Then we sent a push notification to every device using Ionic push.

But in reality, unless you are sending out a marketing push notification you rarely want to send a push to every user that is using your app. More realistically, you want to push to an individual user based on some action in your app. Let’s look at some of the classics, a “like” and a “comment” to give your app instagram like functionality!

Saving Device Tokens

First, we need to consider how we save device tokens and associate them with specific users. On 38Plank, we use a custom NodeJS server with a Mongo database so I decided to save all of the device tokens directly to our users object in our MongoDB instance. I do this on every login / logout so that a user can register multiple devices. The code is in my app.component.ts and it looks like this:

// app.component.ts
  constructor(public platform: Platform,
              public push: Push,
              public events: Events) {}
    
    // ...

    listenToLogin() {
        this.events.subscribe( 'auth' , (user) => {
            if (user) {
                this.registerPush();
            }
        });
    }

    // ...

    registerPush() {
        if (this.platform.is('cordova')) {
        this.push.register().then((t: PushToken) => {
            console.log('Generated Token' + JSON.stringify(t));

            // Register Device with Backend Database
            this.auth.registerDevice(t.token).subscribe( (data) => {
                console.log('Registered with backend');
                }, (err) => {
                console.warn('Error Registering Device with API', err);
            });

            return this.push.saveToken(t);
        }).then( (t: PushToken) => {
            console.log('Token Saved', t);
            this.listenForPush();
        }).catch( (err) => {
            console.log('Error Saving Token: ' , err);
        });
        }
    }

When a users device is saved, we end up with a database structure that looks something like this.

    // This device token is super long, but is a good example
    // User Model
{
    displayName: "Andrew Cole",
    email: "andrew.thielcole@gmail.com",
    deviceTokens:["ejfiC-AhcCQ:APA91bHlQiBArJPJ6yhDaRVjN4OoDvFeQLLjJcpKKn88ou6V-ZEy0XHyC-2Vszh4xebo8PKkZPvRabvHynFWImwC8U006vR8OJg5k5LbzQVuX6weL1WM6-KxxPuVnzNPL7H5yfA", "..."],
}

That way when we want to send a push notification, we can send it to every device the user is registered with.

Using the Push API

Second, we need to think about where we want to generate the push from, either on the device or on your server. If you are not using a serverless architecture like firebase for your app, I would recommend handling it on the backend so that you can offload any heavier processing and schedualing there (redo failed requests, moniter push status…).

While I was developing this feature, I referenced the Ionic Cloud Push API Docs a fair amount, and you should use it as a reference for all of your requests.

Ok, so a user likes a post on your app and you want to send them a notification that someone loves them, that sounds like a great user retention strategy. To do this there are only three steps and ionic makes it pretty easy for us.

1) Gather Device tokens to send

2) Generate Message

3) Send Message

The examples listed below are from a NodeJS Application, but they can be extrapolated to any service that makes http requests (i.e. angular2).

// model/like.ts
// After a Like is recorded
likeSchema.post( 'save' , function(doc: any, next: any) {
    // Find the person who we are sending the push notification to
    User.findOne( { username: result.athleteId })
        .then( (user) => {
            // Returns the user schema from above
            // Create push notification
            if (user.deviceTokens && user.deviceTokens.length > 0 ) {

                // Create the payload for ionic to process
                // Sending to "prod" means that an app delivered directly to the device via xcode will not recieve the message.
                let pushOptions = {
                    tokens: user.deviceTokens,
                    profile: "prod",
                    notification: {
                        message: "" + doc.createdBy + " liked your result!"
                    }
                };

                let pushToken = config.pushToken;

                // Send a http request to Ionics Service, Push Token you can find from your push services setup documented in Part 1 of this blog post serires.
                request({
                    method: 'POST',
                    url: 'https://api.ionic.io/push/notifications',
                    body: pushOptions,
                    headers: {
                        "Content-Type":"application/json",
                        "Authorization": "Bearer " + pushToken
                    },
                    json: true
                }, function(err, response, body) {
                    if (err) {
                        console.log('Error Creating Notification: ' , err);
                    }

                    console.log('Succesfull Notification Created');
                    next();
                });
            } else {
                next();
            }
        });

});

And Viola we have a push notification to a specific users device.

Things we need to mention. First make sure your use of “prod” and “dev” are correct for your testing environment. If you are testing directly on a device, then you need to use “dev” as your profile. If you are testing via test flight or some other beta testing service, then you need to use “prod”

Device tokens is a full array, so if you want to send it to multiple people, just combine the arrays and send.

If you are using Ionics Authentication services, you can also target people based on emails or social authentication. I use my own authentication service, so this is why I need to send directly to device tokens.

In my experiments, messages sent directly to devices usually process pretty quickly, so if you do not recieve a notification on your device within the minute, then something went wrong. ALSO, IF YOU HAVE THE APP OPEN on the device your sending the push to, the app will intercept the notification and you will not see a popup.

Hope this helps you get all setup to start notifiying your users about all the cool things that are happening in your app!


Previous

Push Notification with Ionic 3

One of the things that makes using instagram and pinterest so rewarding is when someone likes your post / photo. That instant gratificaiton when you get a little notification on your device that your friend liked the picture you took keeps you going back for more.

Next

Deeplinks with Ionic 2+

A deeplink is a way to give a user a link to a certain section of your app that a user can respond to. So we could provide a link to a user that looks something like: https://api.38plank.com/deeplink/working+girls+guide