这份文档还在翻译中,预期年底前完成。欢迎您提供宝贵的意见及建议。
Overview
On incoming events such as a new message, or an incoming call, the user often expects to receive a push notification or the app itself. If the app is not active (is in the background), push notifications are the only way to notify app about new events.
This guide explains how to configure your Android app to receive push notifications from the Client SDK.
Set up Firebase project for your Android application
In order to enable push notifications for your Android application, you need to configure your Android application, create a new Firebase project and connect it to your Vonage API application.
Configure Android project
Let's start with setting up Android project.
To add the Client SDK dependency
Add Client SDK to your project.
Add Firebase Cloud Messaging dependency
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:20.3.0")
}
dependencies{
implementation 'com.google.firebase:firebase-messaging:20.3.0'
}
NOTE: The latest version number can be found on the Firebase website.
Implement a custom service class to receive push notifications
If you do not have one already, create a class (service) that extends FirebaseMessagingService
.
In order for Vonage API application to be able to send push notifications to a device, the Vonage server has to know the device token
, also known as InstanceID
.
In your class that extends FirebaseMessagingService
, override onNewToken()
method and update the NexmoClient
by passing new token
:
class MyFirebaseMessagingService: FirebaseMessagingService() {
// We can retrieve client instance only if it has been already initialized
// NexmoClient.Builder().build(context)
private val client = NexmoClient.get()
override fun onNewToken(token: String) {
super.onNewToken(token)
client.enablePushNotifications(token, object: NexmoRequestListener<Void> {
override fun onSuccess(p0: Void?) { }
override fun onError(apiError: NexmoApiError) {}
})
}
}
public class MyFirebaseMessagingService extends FirebaseMessagingService {
// We can retrieve client instance only if it has been already initialized
// new NexmoClient.Builder().build(context)
private NexmoClient client = NexmoClient.get();
@Override
public void onNewToken(@NonNull String token) {
super.onNewToken(token);
client.enablePushNotifications(token, new NexmoRequestListener<Void>() {
@Override
public void onSuccess(@Nullable Void p0) {}
@Override
public void onError(@NonNull NexmoApiError nexmoApiError) {}
});
}
}
Make sure your service is declared in your AndroidManifest.xml
(typically app/src/main/AndroidManifest.xml
) by adding service
tag inside application
tag:
<service android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
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 Vonage server.
Use processPushNotification(message.data, listener)
to process the data received from Firebase Cloud Messaging (FCM) into a ready to use object:
class MyFirebaseMessagingService : FirebaseMessagingService() {
// We can retrieve client instance only if it has been already initialized
// NexmoClient.Builder().build(context)
private val client = NexmoClient.get()
override fun onNewToken(token: String) {
super.onNewToken(token)
//...
}
override fun onMessageReceived(remoteMessage: RemoteMessage) {
// determine if the message is sent from Nexmo server
if (NexmoClient.isNexmoPushNotification(remoteMessage.data)) {
client.processNexmoPush(remoteMessage.data, object : NexmoPushEventListener {
override fun onIncomingCall(call: NexmoCall?) {
Log.d("TAG", "FirebaseMessage:onIncomingCall() with: $call")
}
override fun onNewEvent(event: NexmoEvent?) {
Log.d("TAG", "FirebaseMessage:onNewEvent() with: $event")
}
override fun onError(apiError: NexmoApiError?) {
Log.d("TAG", "FirebaseMessage:onError() with: $apiError")
}
})
}
}
}
public class MyFirebaseMessagingService extends FirebaseMessagingService {
// We can retrieve client instance only if it has been already initialized
// new NexmoClient.Builder().build(context)
private NexmoClient client = NexmoClient.get();
@Override
public void onNewToken(@NonNull String token) {
super.onNewToken(token);
//...
}
@Override
public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
// determine if the message is sent from Nexmo server
if (NexmoClient.isNexmoPushNotification(remoteMessage.getData())) {
client.processNexmoPush(remoteMessage.getData(), new NexmoPushEventListener() {
@Override
public void onIncomingCall(NexmoCall call) {
Log.d("TAG", "FirebaseMessage:onIncomingCall() with: " + call);
}
@Override
public void onNewEvent(NexmoEvent event) {
Log.d("TAG", "FirebaseMessage:onNewEvent() with: " + event);
}
@Override
public void onError(NexmoApiError apiError) {
Log.d("TAG", "FirebaseMessage:onError() with: " + apiError);
}
});
}
}
}
NOTE: In order to apply any methods on the NexmoClient
object (for example answer a call, hangup, and so on), the NexmoClient
has to be initialized and the user has to be logged in to it.
Connect Vonage API application to Firebase
To connect Vonage API Application with Firebase you will need the following:
- Vonage API Application id
- Vonage developer JWT
- Firebase project id
- Firebase token
Get Vonage application Id
Obtain your VONAGE_APP_ID
. You can access existing application in the dashboard. If you don't have an application already you can create the new application via Nexmo CLI.
Generate a Vonage developer JWT
JWTs are used to authenticate a user into the Client SDK.
To generate a VONAGE_DEV_JWT
run the following command. Remember to replace the VONAGE_APP_ID
with id of your Vonage application:
nexmo jwt:generate ./private.key exp=$(($(date +%s)+86400)) acl='{"paths":{"/*/users/**":{},"/*/conversations/**":{},"/*/sessions/**":{},"/*/devices/**":{},"/*/image/**":{},"/*/media/**":{},"/*/applications/**":{},"/*/push/**":{},"/*/knocking/**":{}}}' application_id=VONAGE_APP_ID
NOTE The above commands set the expiry of the JWT to one day from now, which is the maximum.
NOTE A VONAGE_DEV_JWT
is a JWT without a sub claim.
NOTE: More details on how to generate a JWT can be found in the setup guide.
Get Firebase project Id
Get your FIREBASE_PROJECT_ID
from the Firebase console. Navigate to Firebase console -> Project settings -> General
.
Get Firebase token
Get your FIREBASE_TOKEN
from the Firebase console. Navigate to Firebase console -> Project settings -> Service accounts
and generate a new private key.
Link the Vonage backend push service with the Firebase application
To link the Vonage backend push service with the Firebase application you need to make a single request.
Fill VONAGE_APP_ID
, VONAGE_DEV_JWT
, FIREBASE_PROJECT_ID
and FIREBASE_TOKEN
with previously obtained values and run the below command:
VONAGE_APP_ID=
VONAGE_DEV_JWT=
FIREBASE_PROJECT_ID=
FIREBASE_TOKEN=
curl -v -X PUT \
-H "Authorization: Bearer $VONAGE_DEV_JWT" \
-H "Content-Type: application/json" \
-d "{\"token\":\"$FIREBASE_TOKEN\", \"projectId\":\"$FIREBASE_PROJECT_ID\"}" \
https://api.nexmo.com/v1/applications/$VONAGE_APP_ID/push_tokens/android
Putting it all together
Now you can test your push notification setup by calling any user. Incoming call will trigger onIncomingCall
callback presented above.
Conclusion
In this guide you have seen how to set up push notifications.
Overview
On incoming events such as a new message, or an incoming call, the user often expects to receive a push notification, if the app is not active.
There are two types of push notifications that you can use:
- VoIP push (PushKit) - the better fit for applications that use Vonage In-App Voice functionality.
- Regular push (UserNotifications) - the better fit for applications that use Vonage In-App Chat functionality.
This guide will cover how to VoIP push notifications with the Client SDK.
Create a push certificate
Apple Push Notifications service (APNs) uses certificate-based authentication to secure the connections between APNs and Vonage servers. So you will need to create a certificate and upload it to the Vonage Servers.
Adding a push notification capability
To use push notifications you are required to add the push notification capability to your Xcode project. To do this select your target and select Signing & Capabilities:
Then select add capability and add the Push Notifications capability:
If Xcode is automatically managing the signing of your app it will update the provisioning profile linked to your Bundle Identifier to include the capability.
Generating a push certificate
To generate a push certificate you will need to log in to your Apple developer account and head to the Certificates, Identifiers & Profiles page and add a new certificate:
Choose a VoIP Services Certificate and continue. You will now need to choose the App ID for the app that you want to add VoIP push notifications to and continue. If your app is not listed you will have to create an App ID. Xcode can do this for you if it automatically if it manages your signing for you, otherwise you can create a new App ID on the Certificates, Identifiers & Profiles page under Identifiers. Make sure to select the push notifications capability when doing so.
You will be prompted to upload a Certificate Signing Request (CSR). You can follow the instructions on Apple's help website to create a CSR on your Mac. Once the CSR is uploaded you will be able to download the certificate. Double click the .cer
file to install it in Keychain Access.
To get the push certificate in the format that is needed by the Vonage servers you will need to export it. Locate your VoIP Services certificate in Keychain Access and right-click to export it. Name the export applecert
and select .p12
as the format:
You can find more details about connecting to APNs in Apple's official documentation.
Upload your certificate
You upload your certificate to the Vonage servers by making a POST request. The iOS Push Certificate Uploading Tool, available on GitHub, does so with a user interface. Either of the following methods needs your Vonage Application ID. It can be obtained from the dashboard.
Using the Upload Tool
To use the tool you will need to run it locally or deploy it. You can follow the the instructions in the GitHub project's README. You will also need the private key for your Vonage Application.
Once you have the tool running, enter your Vonage Application ID, private key, and certificate file and upload. The status of your upload will be shown on the page once it is complete.
Using the Terminal
In addition to your Vonage Application ID to upload using the terminal, you will also need 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.
Then 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 application
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 Background Mode for your app
Similar to the process for adding the push notifications capability earlier, in Xcode, under your target, open Capabilities and select Background Modes. Once the capability is added tick the "Voice over IP" option:
2. Import PushKit
, adopt PKPushRegistryDelegate
, and sign up to VoIP notifications
Add a voipRegistry
property:
let voipRegistry = PKPushRegistry(queue: nil)
and set it up:
func registerForVoIPPushes() {
self.voipRegistry.delegate = self
self.voipRegistry.desiredPushTypes = [PKPushType.voIP]
}
Add a voipRegistry
property:
@property PKPushRegistry* voipRegistry;
and set it up:
- (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 code to handle an incoming VoIP push notification
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith
payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
if(NXMClient.shared.isNexmoPush(userInfo: payload.dictionaryPayload)) {
guard let pushPayload = NXMClient.shared.processNexmoPushPayload(payload.dictionaryPayload) else {
NSLog("Not a Nexmo push notification")
return
}
}
}
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload
forType:(PKPushType)type withCompletionHandler:(void (^)(void))completion {
if ([NXMClient.shared isNexmoPushWithUserInfo:payload.dictionaryPayload]) {
NXMPushPayload *pushPayload = [NXMClient.shared processNexmoPushPayload:payload.dictionaryPayload];
if (!pushPayload){
NSLog(@"Not a nexmo push");
return;
};
}
}
For the SDK to process the push properly NXMClient
should be logged in.
4. Enable push notifications through a logged in NXMClient
NXMClient.shared.enablePushNotifications(withPushKitToken: pushKitToken,
userNotificationToken: nil, isSandbox: true) { (error) in
// code
}
[NXMClient.shared enablePushNotificationsWithPushKitToken:pushKitToken
userNotificationToken:userNotificationToken isSandbox:YES
completionHandler:^(NSError * _Nullable error) {
// code
}];
'isSandbox'
isYES
/true
for an app using the Apple sandbox push servers and NO/false for an app using the Apple production push servers.'pushKitToken'
is the token received inpushRegistry(_:didUpdate:for:)
.
Conclusion
In this guide you have seen how to set up push notifications.