If you have an SAPUI5 app mobilised using SAP Cloud Platform (CP) mobile service for SAP Fiori, commonly called Fiori Mobile, you can also add push capabilities to it. But if you did not read my first article, go back there and read it, otherwise you will feel something is missing:
How to mobilize your HTML5/SAPUI5 app with Fiori Mobile.
In order to continue what we started in the previous blog article, let us use that app and add mobile capabilities to that. Remember that this article is Android focused, but that you can do the same for iOS if you have a developer certificate.
1. Create an app on Google Developers and enable it for GCM
You certainly know push notifications. The ones that are shown in your device's screen, even when it is locked saying you received an email, a new version of a app has been released or that somebody like your picture in a social network. However, some people do not know how it works and that there is a service of the company that developed you device's operational system responsible for delivering these notification to you.
See below a brief explanation for Android devices, that are served by Google Cloud Messaging service (GCM):
1. Android device sends sender id and application id to GCM server for registration.
2. GCM server issues registration id to android device.
3. Device sends registration id to your server (in our case, SAP CP, mobile service for development and operations server).
4. Your server stores registration for later usage.
a. When needed, your server sends a message to GCM server along with device registration id.
b. GCM server delivers that message to your mobile device using device registration id.
Let us go to the action!
Login to the Google Developers portal for Android:
https://developers.google.com/mobile/add?platform=android
Enter the following data.
App name: fiorimobileex
Android package name: com.sap.fiorimobileex
Click on
Choose and configure service button.
Select
Cloud Messaging.
Click on
ENABLE GOOGLE CLOUD MESSAGING.
Take note of the Server API Key and Sender ID. You will need to add this data to your mobile app configuration on Fiori Mobile.
2. Configure Android Push Notification Settings on Fiori Mobile
The push configuration values got in the last step now must be set on SAP Fiori Mobile's Admin Console.
Go to SAP CP cockpit,
Services and click on
Fiori Mobile.
Click on
Go to Admin Console.
Click on
Applications >
Manage Apps, then on the name of your app.
Go to
App Settings >
Notifications >
Android and add the API Key and Sender ID that you got from GCM registration.
Finally save it.
3. Add push notifications code to you app
To support push notifications, you must register your device with Google Play Services and SAP CP mobile service for development & operations. The Kapsel Push Plugin does both for you.
Go to SAP CP cockpit,
Services and click on
SAP Web IDE., then on
Open SAP Web IDE.
Right click on the
model folder in your project and select
New >
File.
Name the file
Push.js.
Paste the following code to this file:
sap.ui.define([], function() {
"use strict";
return {
regSuccess: function(result) {
console.log("Successfully registered: " + JSON.stringify(result));
},
regFailure: function(errorInfo) {
console.log("Error while registering. " + JSON.stringify(errorInfo));
},
registerForPush: function() {
console.log("attempting to register for notifications");
var nTypes = sap.Push.notificationType.SOUNDS | sap.Push.notificationType.ALERT;
//TODO #1 - Set your Sender ID
sap.Push.registerForNotificationTypes(nTypes, this.regSuccess, this.regFailure, this.processNotification, "<Your Sender ID>"); //GCM Sender ID, null for APNS
},
unregisterForPush: function() {
sap.Push.unregisterForNotificationTypes(this.unregCallback);
},
unregCallback: function(result) {
console.log("Successfully unregistered: " + JSON.stringify(result));
},
processNotification: function(notification) {
console.log("Received a notifcation: " + JSON.stringify(notification));
alert("Received a notifcation: " + JSON.stringify(notification));
if (sap.Push.isPlatformIOS()) {
sap.Push.resetBadge(this.resetBadgeSuccess);
}
},
processMissedNotification: function(notification) {
if (notification) {
console.log("Received a missed notification: " + JSON.stringify(notification));
alert("Received a missed notification: " + JSON.stringify(notification));
}
if (sap.Push.isPlatformIOS()) {
sap.Push.resetBadge(this.resetBadgeSuccess);
}
},
resetBadgeSuccess: function(result) {
console.log("Badge has been reset: " + JSON.stringify(result));
},
checkForNotification: function() {
sap.Push.checkForNotification(this.processMissedNotification);
}
};
});
It is important that you through this file to understand the source code. If you have questions about the used APIs, please refer to
Push API Reference.
Locate
//TODO #1 comment. In the line of code under this comment, set the sender ID that you got from GCM registration.
It should look like this:
Save your changes to
Push.js.
Open your
Component.js file
. Add the code highlighted in red below.
sap.ui.define([
"sap/ui/core/UIComponent",
"sap/ui/Device",
"com/sap/northwind/model/models",
"com/sap/northwind/controller/ListSelector",
"com/sap/northwind/controller/ErrorHandler",
"com/sap/northwind/model/Push"
], function (UIComponent, Device, models, ListSelector, ErrorHandler, Push) {
"use strict";
return UIComponent.extend("com.sap.northwind.Component", {
metadata : {
manifest : "json"
},
/**
* The component is initialized by UI5 automatically during the startup of the app and calls the init method once.
* In this method, the device models are set and the router is initialized.
* @public
* @override
*/
init : function () {
this.oListSelector = new ListSelector();
this._oErrorHandler = new ErrorHandler(this);
// set the device model
this.setModel(models.createDeviceModel(), "device");
// call the base component's init function and create the App view
UIComponent.prototype.init.apply(this, arguments);
// create the views based on the url/hash
this.getRouter().initialize();
// if it not in a mobile device
if (!sap.ui.Device.system.desktop) {
// register for push
Push.registerForPush();
}
},
Save your changes.
You should still be able to test your application from Web IDE. The mobile bits of the code will be ignored when running in a browser.
4. Redeploy to SAP CP
For the new changes to take effect, you must redeploy the your app to SAP CP (old HCP). There is no need to reregister to Fiori Launchpad if you did so before.
Select
FioriMobileEx, right click and select
Deploy >
Deploy to SAP Cloud Platform.
Leave the values as default and click on
Deploy.
A window will appear with a successful message.
Click on
Close.
5. Rebuild your packaged app with Fiori Mobile
Now it is time to package you app for testing.
Select the FioriMobileEx folder
, right-click and select
Fiori Mobile >
Build Packaged App.
A wizard will open. Leave the values as default and click on
Next.
Select
Android, then open the drop-down menu and select your signing profile.
Click on
Next, then on
Build.
Your build will start.
Once the build finishes, a QR code should appear to allow you to download and install the
FioriMobileEx app on your device.
Install and run it on your Android device.
6. Get you app's ID on SAP CP, mobile service for development and operations cockpit
In order to test our app sending push notifications, we need to get its ID on SAP CP, mobile service for development and operations cockpit. This ID is generated during the registration (logon) process.
On SAP CP Cockpit
, left pane, go to
Services, select
Mobile Services Development & Operations.
Click on
Go to Service.
The Mobile Service for Development and Operations home page will open.
Click on
Applications.
Look for the
FioriMobileEx app and take notes of its
Application ID. It is something like
com.sap.mobilesecure.XXX.
This is important because push notifications can be sent to those users registered to a specific application ID.
Now click on
Registrations and Users.
Change the time range to include the time when your user registered against SAP CP, mobile service for development and operations and take notes of the registration ID.
This is important because push notifications can be sent to a specific user registered to a specific application ID.
7. Test your app for push notifications using a REST Client
SAP CP, mobile service for Development & Operations provides a Rest API to send notifications. Let us use now the application
and registration IDs to send push notifications to our mobile devices.
Open a REST Client. We are using
Postman in this exercise.
Call the REST API to send a notification to all users of an app using the following information:
URL: https://hcpms-<USER_ID>trial.hanatrial.ondemand.com/restnotification/application/<APPLICATION_ID>;
Header Content-Type: application/json
Header Cache-Control: no-cache
Request Body:
{
"alert": "Hello World!",
"badge": 1,
"data": "This is just a test",
"sound": "soundval"
}
Change the
HTTP method to
POST, click on
Authorization tab, enter your HCP credentials and click on
Update Request.
Click on
Body tab and enter the payload as suggested above.
Your REST client should now look like the following, so click on
Send.
In the response, you should get a 201 status code.
You should see the notification in your device.
Now, repeat the steps above to call the Rest API to send a notification to a specific user through the
registration ID. See below the information you should use:
URL: https://hcpms-<USER_ID>trial.hanatrial.ondemand.com/restnotification/application/<REGISTRATION_ID>;
Header Content-Type: application/json
Header Cache-Control: no-cache
Request Body:
{
"alert": "Hello World!",
"badge": 1,
"data": "This is just a test",
"sound": "soundval"
}
Your REST client should now look like the following. So, click on
Send and check the response.
You should get a 201 status code.
That’s it. Now you are a true Mobile Developer!!!
8. Thinking about a real case
As you know, this is just an example of how to add push capabilities to your mobile SAPUI5 app using Fiori Mobile. So, let us think about a real case, when the backend is responsible for sending push notifications.
Imagine a very simple app of vacation approval, where managers go to approve vacation requests from their employees. A good scenario using push notifications here is to send a push notification to the manager's device when a vacation request is submitted by an employee.
Certainly, the employee will not send a push notification manually to his manager. The backed should trigger a POST HTTP command to SAP CP, mobile service for development and operations server when the vacation request is submitted by this employee.
But the real question is: how to send this notification to the specific manager of the employee that submitted the vacation request? Imagine you send it to all managers of the company. They are going to get crazy with the vacation requests of the whole company being notified to them. It does not make any sense. This is why you need to store a delivery address. You need to know how to bring this notification to the right manager.
But what is a delivery address? Remember we have used Postman to send push notifications. There, we defined a Request URL using an application or registration ID:
https://hcpms-<ACCOUNT_NAME>.hanatrial.ondemand.com/restnotification/application/<REGISTRATION_ID>;. That is our delivery address, i.e. the address to reach a specific device.
I show here an example of source code to build the delivery address with the app context that is available when using Fiori Mobile. For those that already used the Kapsel logon plugin with HAT or manually, you will notice that the logon app context data structure is totally different.
For example,
appContext.registrationContext.serverHost does not contain anymore (comparing to HAT or manual builds) the SAP CP, mobile service for development and operations server address, but the Portal server address:
flpportal-<ACCOUNT_NAME>.dispatcher.hanatrial.ondemand.com. So, the code below shows an example of code to build the delivery address, taking from the Portal server host the SAP CP account name. It is called the first time the app is executed, when the logon process is ready, so every manager will have his delivery address stored in the backend for future use.
The URL I use as delivery address is
https://hcpms-<ACCOUNT_NAME>.hanatrial.ondemand.com/restnotification/application/<REGISTRATION_ID>;. With this URL, it is possible to delivery a push notification to a specific device. See the source below that is inside a controller file:
// initial event
onInit : function() {
var that = this;
...
// if it a mobile device
if (!sap.ui.Device.system.desktop) {
// get the logon context passing a success and an error callbacks
sap.logon.Core.getContext(
//success call back
function(result) {
// call the function that will store the delivery address for future use
that.subscribeForPushNotifications(result);
console.log("Successfully got the app context");
},
//error call back
function() {
console.log("Failed to get the app context");
}
);
}
},
subscribeForPushNotifications: function(appContext) {
var HCPAccount, serverHost, deliveryAddress, oSubscription;
// if the app context is not null
if (appContext) {
// build the delivery address
serverHost = appContext.registrationContext.serverHost;
HCPAccount = serverHost.substring(serverHost.indexOf("-")+1, serverHost.indexOf("."));
deliveryAddress = "https://hcpms-" + HCPAccount +
".hanatrial.ondemand.com/restnotification/registration/" +
appContext.applicationConnectionId;
oSubscription = {};
var d = new Date();
var t = d.getTime();
oSubscription.LASTUPDATED = "/Date(" + t + ")/";
oSubscription.DEVICEID = appContext.applicationConnectionId;
oSubscription.DELIVERYADDRESS = deliveryAddress;
oSubscription.TITLE = "Test";
oSubscription.MOBILEUSER = appContext.registrationContext.user.toUpperCase();
var oModel = this.getOwnerComponent().getModel();
// storing the delivery address
oModel.create("/Subscription", oSubscription, null, this._subscriptionCreateSuccess, this._subscriptionCreateError);
} else {
console.log("Application context is null!");
}
},
_subscriptionCreateSuccess: function(oData, response) {
console.log("Successfully subscribed for event");
},
_subscriptionCreateError: function(oError) {
console.log("Failed to subscribe to event");
},
As you saw in the source code above, we built the delivery address of a manager's device and then we stored it in the backed using an OData service. Now, when a new vacation request is submitted by an employee, a function in the backend should be triggered to check inside the Subscription table what is the delivery address of the manager that is responsible for approving it (look for his user).
With that in hands, this function should build an HTTP POST message and send it to SAP CP, mobile service for development and operations server, that will pass this message to GCM / APNS server, that will bring the message to the manager's device. See the following diagram that will help you to understand the process:
This is a proposal of solution for a production app. I hope it can help you.