How to Set Up Nexmo Push Notifications on Android

On incoming events, such as when a user receives a new message, or an incoming call, the user often expects to receive a push notification, if the app is not active.

This tutorial explains how to configure your Android app to receive push notifications from Nexmo Client SDK.

Set up Firebase project for your app

In order to enable push notifications for your Android app, you should use the Firebase Cloud Messaging (FCM) API. To do that, start by adding Firebase to your Android project.

In case you have not done that already, more details can be found in the official Firebase documentation.

Provision your server key

Obtain a jwt_dev, which is a jwt without a sub claim. More details on how to generate a JWT can be found in the setup guide.

Get your server_api_key from Firebase console. Navigate to Firebase console --> project settings --> CloudMessaging Tab --> Server key

Get your Nexmo Application ID, app_id. It can be obtained from Nexmo Dashboard.

Run the following Curl command, replacing jwt_dev, server_api_key, app_id with your values:

curl -v -X PUT \
   -H "Authorization: Bearer $jwt_dev" \
   -H "Content-Type: application/json" \
   -d "{\"token\":\"$server_api_key\"}" \
   https://api.nexmo.com/v1/applications/$app_id/push_tokens/android

Add Firebase Cloud Messaging to your Android project

In your IDE, in your app level build.gradle file (usually app/build.gradle), add the firebase-messaging dependency:

dependencies{
    implementation 'com.google.firebase:firebase-messaging:x.y.z'
}

You need to replace x.y.z with the latest Cloud Messaging versions number, which can be found on the Firebase website.

Implement a service to receive push notifications

If you do not have one already, create a service that extends FirebaseMessagingService. Make sure your service is declared in your AndroidManifest.xml:

<service android:name=".MyFirebaseMessagingService">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

Enable Nexmo server to send push notifications to your device

In order for Nexmo to be able to send push notification to a device, the Nexmo server has to know the device token, also known as InstanceID.

In your implementation of FirebaseMessagingService, override onNewToken() and update the Nexmo servers with it:

override fun onNewToken(token: String?) {
    token?.let {
        NexmoClient.get().enablePushNotifications(token, requestListener)
    }
}

Receive push notifications

Push notifications are received in your implementation of MyFirebaseMessagingService, on onMessageReceived() method.

You can use NexmoClient.isNexmoPushNotification(message.data)) to determine if the message is sent from Nexmo server.

Use NexmoClient.get().processPushNotification(message.data, listener) to process the data received from Firebase Cloud Messaging (FCM) into an easy to use Nexmo object.

For example, in your MyFirebaseMessagingService:

 val pushEventListener = object : NexmoPushEventListener {
        override fun onIncomingCall(p0: NexmoCall?, p1: MemberEvent?) {
            TODO("not implemented")
        }

        override fun onNewEvent(p0: NexmoEvent?) {
            TODO("not implemented")
        }

        override fun onError(p0: NexmoApiError?) {
            TODO("not implemented")
        }
    }

    override fun onMessageReceived(message: RemoteMessage?) {
        message?.data?.let {
            if (NexmoClient.isCommsPushNotification(message.data)) {
                NexmoClient.get().processPushNotification(message.data, pushEventListener)
            }

        }
    }

Note: in order to apply any methods on Nexmo Client object (for example answer a call, hangup, and so on) Nexmo Client has to be initialized and the user has to be logged in to it.

Conclusion

In this tutorial you have seen how to set up push notifications.

How to Set Up Nexmo Push Notifications on iOS

On incoming events, such as when a user receives a new message, or an incoming call, the user often expects to receive a push notification, if the app is not active.

This tutorial explains how to configure your iOS app to receive push notifications from Nexmo Client SDK.

Create a push certificate

Log in to your Apple developer account and create a push certificate for your app. Find more details in Apple's official documentation.

Download your certificate. In the next step the downloaded certificate name is referred to as applecert.p12.

Upload your certificate

Obtain a jwt_dev, which is a jwt without a sub claim. More details on how to generate a JWT can be found in the setup guide.

Get your Nexmo Application ID, app_id. It can be obtained from Nexmo Dashboard.

Run the following Curl command, replacing jwt_dev, applecert.p12, app_id with your values:

hexdump -ve '1/1 "%.2x"' < applecert.p12 > applecert.pfx.hex
hextoken=`cat applecert.pfx.hex`

curl -v -X PUT \
   -H "Authorization: Bearer $jwt_dev" \
   -H "Content-Type: application/json" \
   -d "{\"token\":\"$hextoken\"}" \
   https://api.nexmo.com/v1/applications/$app_id/push_tokens/ios

Integrate push notifications in your app

There are two types of push notifications that you can use:

  • Voip push - the better fit for apps which utilizes Nexmo In-App Voice funcionality
  • Regular push

Integrate VOIP push

VOIP push notifications are suitable for VOIP apps. Among other benefits, it allows you to receive notifications even when the app is terminated.

To integrate VOIP push in your app, follow these steps:

1. Enable VOIP push notifications for your app.

In XCode under your target, open Capabilities:

  • Enable Push Notifications
  • Enable background modes with Voice over IP selected
2. Import PushKit, adopt PKPushRegistryDelegate and sign to VOIP notifications:

Swift:

func registerForVoIPPushes() {
    self.voipRegistry = PKPushRegistry(queue: nil)
    self.voipRegistry.delegate = self
    self.voipRegistry.desiredPushTypes = [PKPushTypeVoIP]
}

Objective-C:

- (void) registerForVoIPPushes {
    self.voipRegistry = [[PKPushRegistry alloc] initWithQueue:nil];
    self.voipRegistry.delegate = self;

    // Initiate registration.
    self.voipRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
}
3. Implement the following delegate method and add the the code to handle an incoming VOIP push notification:

Swift:

func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, 
        for type: PKPushType, completion: @escaping () -> Void) {
    if(client.isNexmoPush(userInfo: payload.dictionaryPayload)) {
        client.processNexmoPush(userInfo: payload.dictionaryPayload) { (error: Error?) in
            //Code
        }
    }
}

Objective-C:

- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload 
        forType:(PKPushType)type withCompletionHandler:(void (^)(void))completion {
    if([client isNexmoPushWithUserInfo: payload.dictionaryPayload]) {
        [client processNexmoPushWithUserInfo:payload.dictionaryPayload completion:^(NSError * _Nullable error) {
            //Code
        }];
    }
}

For the SDK to process the push properly NXMClient should be logged in.

4. Enable Nexmo push notifications through a logged in NXMClient:

Swift:

client.enablePushNotifications(withDeviceToken: deviceToken, isPushKit: true, isSandbox: isSandbox) { error in 
    //Code
}

Objective-C:

[client enablePushNotificationsWithDeviceToken:'deviceToken' isPushKit:YES isSandbox:'isSandbox' completion:^(NSError * _Nullable error) {
    //Code
}];
  • 'isSandbox' is YES/true for an app using the Apple sandbox push servers and NO/false for an app using the Apple production push servers.

  • 'deviceToken' is the token received in application:didRegisterForRemoteNotificationsWithDeviceToken:.

Integrate Regular Push

If your app is not a VOIP app, you should use regular push notifications. Nexmo push is sent silently to allow you control over what is presented to your user.

To receive silent push notifications in your app use the following steps.

1. Enable push notifications for your app.

In XCode under your target, open Capabilities:

* enable Push Notifications * enable background modes with remote notifications selected

2. Register for device token.

In your app delegate implement the following delegate method to receive a device token:

Swift:

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)

Objective-C:

-(void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;
3. Handle an incoming push notification

In your app delegate adopt the UNUserNotificationCenterDelegate.

Implement the following delegate method and add the the code to handle an incoming push notification:

Swift:

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    if(client.isNexmoPush(userInfo: userInfo)) {
        client.processNexmoPush(userInfo: userInfo) { (error: Error?) in
            //Code
        }
    }
}

Objective-C:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler {
            if([client isNexmoPushWithUserInfo:userInfo]) {
                [client processNexmoPushWithuserInfo:userInfo completion:^(NSError * _Nullable error) {
                    //Code
                }];
            }
    }

For the SDK to process the push properly the NXMClient needs to be logged in.

4. Enable Nexmo push notifications through a logged in NXMClient:

Swift:

client.enablePushNotifications(withDeviceToken: deviceToken, isPushKit: false, isSandbox: isSandbox) { (error: Error?) in 
    //Code    
}

Objective-C:

[client enablePushNotificationsWithDeviceToken:'deviceToken' isPushKit:NO isSandbox:'isSandbox' completion:^(NSError * _Nullable error) {
                //Code
            }];
  • 'isSandbox' is YES/true for an app using the Apple sandbox push servers and NO/false for an app using the Apple production push servers.
  • 'deviceToken' is the token received in application:didRegisterForRemoteNotificationsWithDeviceToken:.

Conclusion

In this tutorial you have seen how to set up push notifications.