How to trigger an alert once receiving push notifications using Broadcast notifications? - push-notification

Using MobileFirst Platform 6.3,
I am implementing the sendMessage API from WL.Server for pushing notification to all devices (Push.ALL).
The notification is successfully pushed into the device but it doesn't trigger an alert like NotifyAllDevice (as can be seen in the sample project for push notifications).
What can I do to trigger a dialog box with the message inside it, after the notification has arrived to my device?
function sendMessage(msg){
var notificationOptions = {};
notificationOptions.type = 0;
notificationOptions.message = {};
notificationOptions.message.alert = msg;
notificationOptions.target = {};
notificationOptions.target.platform = ['G','A'];
// set notification properties for GCM
notificationOptions.settings = {};
notificationOptions.settings.gcm = {};
notificationOptions.settings.gcm.sound = "default";
// set notification properties for APNS
notificationOptions.settings.apns = {};
notificationOptions.settings.apns.sound = "default";
//WL.Server.notifyAllDevices(userSubscription, notification);
WL.Server.sendMessage("PushNotifications", notificationOptions);
return {
result: "Notification sent to user :: "
};
}

For broadcast / tag based messages, the notifications are received on the client / app. in the callback
WL.Client.Push.onMessage(props, payload)
More info. on the API is found at -
http://www-01.ibm.com/support/knowledgecenter/SSZH4A_6.2.0/com.ibm.worklight.apiref.doc/html/refjavascript-client/html/WL.Client.Push.html%23onMessage
Here's how you would define the callback and display an in the app:
WL.Client.Push.onMessage = function(props, payload) {
alert("broadcastReceived invoked");
alert("props :: " + JSON.stringify(props));
alert("payload :: " + JSON.stringify(payload));
};

Related

Unable to send notification from an Expo React Native App using Azure Notification Hub REST API

I am trying to receive notifications in an Expo React Native App.
The notifications will be sent using Azure Notification Hub REST API
I followed the steps below :
Added the Android project in Firebase Console
To get the Server Key I followed - Firebase messaging, where to get Server Key?
Configured the FCM ServerKey in Azure Notification Hub
Added the google-services.json at the root in my React Native App and modified app.json as mentioned in - https://docs.expo.dev/push-notifications/using-fcm/
To register in ANH, we first need the SAS Token - https://learn.microsoft.com/en-us/rest/api/notificationhubs/common-concepts I generated the token with the following code
const Crypto = require('crypto-js');
const resourceURI =
'http://myNotifHubNameSpace.servicebus.windows.net/myNotifHubName ';
const sasKeyName = 'DefaultListenSharedAccessSignature';
const sasKeyValue = 'xxxxxxxxxxxx';
const expiresInMins = 200;
let sasToken;
let location;
let registrationID;
let deviceToken;
function getSASToken(targetUri, sharedKey, ruleId, expiresInMins) {
targetUri = encodeURIComponent(targetUri.toLowerCase()).toLowerCase();
// Set expiration in seconds
var expireOnDate = new Date();
expireOnDate.setMinutes(expireOnDate.getMinutes() + expiresInMins);
var expires =
Date.UTC(
expireOnDate.getUTCFullYear(),
expireOnDate.getUTCMonth(),
expireOnDate.getUTCDate(),
expireOnDate.getUTCHours(),
expireOnDate.getUTCMinutes(),
expireOnDate.getUTCSeconds()
) / 1000;
var tosign = targetUri + '\n' + expires;
// using CryptoJS
//var signature = CryptoJS.HmacSHA256(tosign, sharedKey);
var signature = Crypto.HmacSHA256(tosign, sharedKey);
var base64signature = signature.toString(Crypto.enc.Base64);
//var base64signature = signature.toString(CryptoJS.enc.Base64);
var base64UriEncoded = encodeURIComponent(base64signature);
// construct autorization string
var token =
'SharedAccessSignature sr=' +
targetUri +
'&sig=' +
base64UriEncoded +
'&se=' +
expires +
'&skn=' +
ruleId;
console.log('signature:' + token);
return token;
}
I then called the create registration API - https://learn.microsoft.com/en-us/rest/api/notificationhubs/create-registration-id
The registrationID has to be extracted from the response header of the API Call
I used the following code to generate the ANH Regsitration ID
async function createRegistrationId() {
const endpoint =
'https://xxxxxx.servicebus.windows.net/xxxxxxx/registrationIDs/?api-version=2015-01';
sasToken = getSASToken(resourceURI, sasKeyValue, sasKeyName, expiresInMins);
const headers = {
Authorization: sasToken,
};
const options = {
method: 'POST',
headers: headers,
};
const response = await fetch(endpoint, options);
if (response.status !== 201) {
console.log(
'Unbale to create registration ID. Status Code: ' + response.status
);
}
console.log('Response Object : ', response);
for (var pair of response.headers.entries()) {
//console.log(pair[0] + ': ' + pair[1]);
}
location = response.headers.get('Location');
console.log('Location - ' + location);
console.log('Type - ' + response.type);
registrationID = location.substring(
location.lastIndexOf('registrationIDs/') + 'registrationIDs/'.length,
location.lastIndexOf('?api-version=2015-01')
);
console.log('Regsitration ID - ', registrationID);
return location;
}
Next step was to update this registration ID in ANH with the Native Device Token
I used expo-notifications package and the method getDevicePushTokenAsync() method to get the native device token
async function registerForPushNotificationsAsync() {
let token;
if (Device.isDevice) {
const { status: existingStatus } = await Notifications.getPermissionsAsync();
let finalStatus = existingStatus;
if (existingStatus !== 'granted') {
const {
status
} = await Notifications.requestPermissionsAsync();
finalStatus = status;
}
if (finalStatus !== 'granted') {
alert('Failed to get push token for push notification!');
return;
}
token = (await Notifications.getDevicePushTokenAsync()).data;
console.log(token);
} else {
alert('Must use physical device for Push Notifications');
}
if (Platform.OS === 'android') {
Notifications.setNotificationChannelAsync('default', {
name: 'default',
importance: Notifications.AndroidImportance.MAX,
vibrationPattern: [0, 250, 250, 250],
lightColor: '#FF231F7C',
});
}
return token;
}
The native device token was in the following format on Android device
c6RI81R7Rn66kWZ0rar3M2:APA91bEcbLXGwEZF-8hu1yGHfXgWBNuxr_4NY_MR8d7HEzeHAJrjoJnjUlneAIiVglCNIGUr11qkP1G4S76bx_H7NItxfQhZa_bgnQjqSlSaY4-oCoarDYWcY-Mz_ulW8rQZFy_SA6_j
I then called the updateRegistrationId API - https://learn.microsoft.com/en-us/rest/api/notificationhubs/create-update-registration
async function updateRegistraitonId() {
//IF you use registrationIDs as in returned location it was giving 401 error
const endpoint =
'https://xxxxx.servicebus.windows.net/xxxxxxx/registrations/' +
registrationID +
'?api-version=2015-01';
const endpoint1 = location;
const headers = {
Authorization: sasToken,
'Content-Type': 'application/atom+xml;type=entry;charset=utf-8',
};
//Remember to create well-formed XML using back-ticks
//else you may get 400 error
//If you use the tags element it was giving an error
const regDATA = `<entry xmlns="http://www.w3.org/2005/Atom">
<content type="application/xml">
<GcmRegistrationDescription xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/netservices/2010/10/servicebus/connect">
<GcmRegistrationId>${deviceToken}</GcmRegistrationId>
</GcmRegistrationDescription>
</content>
</entry>`;
const options = {
method: 'PUT',
headers: headers,
body: regDATA,
};
const response = await fetch(endpoint, options);
if (response.status !== 201) {
console.log(
'Looks like there was a problem. Status Code: ' + response.status
);
console.log('Response Object : ', response);
//return;
}
}
According to API documentation, I should get 201 response, I got 200 response code . I am not sure if this is the issue
After this I had the notification handling code to recieve the notification,similar to the code in - https://docs.expo.dev/versions/latest/sdk/notifications/
I then tried to send notification using Test Send from ANH, it failed with the error -
**
"The Token obtained from the Token Provider is wrong"
**
I checked in ANH Metrics, the error was categorized as GCM Authentication error, GCM Result:Mismatch SenderId
I tried to check for documentation to add the SenderId , but I couldnt find anyway to inlcude the SenderId also in the payload of updateRegistration call (in xml atom entry)
I tried to use the device token and send directly from Firebase Console, I did not receive it either.
I used the Direct Send API of Azure notification Hub but still did not receive anything
I am suspecting there could be some issue in the way I am handling notifiations in the client device, I can fix that later , but first I will have to resolve the error I am getting in Test Send in Azure NH
Any help to be able to successfully send using Test Send in ANH or pointers ahead for next steps will be much appreciated

Under the hood of Send function in masstranssit

I'm trying to send command to rabbitMQ by masstransit while i know difference between send and publish , defined a direct exchange but use Send to transit that message after that i'm getting error that "Exchange name" received fanout but current is direct .
Does Send makes exchange to fanout type?
config.ReceiveEndpoint("test-consumer", consumer =>
{
consumer.Lazy = true;
consumer.Consumer<TestConsumer>();
consumer.Durable = true;
consumer.ConfigureConsumeTopology = false;
consumer.Bind("MyExchange", ex =>
{
ex.ExchangeType = ExchangeType.Direct;
ex.RoutingKey = "reza";
});
//binding type from test-consumer exchange to test-consumer queue
// consumer.ExchangeType = "direct";
});
var endPoint = await bus.GetSendEndpoint(new Uri("exchange:MyExchange"));
var send3 = rezEndPoint.Send(new Test { Messaged = "sent from myExchange" },h=> { h.SetRoutingKey("reze"); } );
Since you are specifying the exchange type as direct in the consumer, you need to also set that via the send endpoint:
var endPoint = await bus.GetSendEndpoint(new Uri("exchange:MyExchange?type=direct"));

pushPlugin notification on the server and front-en

does this get triggered again from the server containing a message?
"ecb":"window.onNotificationGCM"
I have this set up on the server
device_tokens = [], //create array for storing device tokens
retry_times = 4, //the number of times to retry sending the message if it failed
sender = new gcm.Sender('AIzaSyDpA0b2smrKyDUSaP0Cmz9hz4cQ19Rxn7U'), //create a new sender
message = new gcm.Message(); //create a new message
message.addData('title', 'Open Circles');
message.addData('message', req.query.message);
message.addData('sound', 'notification');
message.collapseKey = 'testing'; //grouping messages
message.delayWhileIdle = true; //delay sending while receiving device is offline
message.timeToLive = 3; //the number of seconds to keep the message on the server if the device is offline
device_tokens.push(val.deviceToken);
sender.send(message, device_tokens, retry_times, function(result){
console.log(result);
console.log('push sent to: ' + val.deviceToken);
});
So what I want to know is, once a server call is made will it trigger the notification on the front. What am I missing about this system?
case 'message':
// if this flag is set, this notification happened while we were in the foreground.
// you might want to play a sound to get the user's attention, throw up a dialog, etc.
if (event.foreground) {
console.log('INLINE NOTIFICATION');
var my_media = new Media("/android_asset/www/" + event.soundname);
my_media.play();
} else {
if (event.coldstart) {
console.log('COLDSTART NOTIFICATION');
} else {
console.log('BACKGROUND NOTIFICATION');
}
}
navigator.notification.alert(event.payload.message);
console.log('MESSAGE -> MSG: ' + event.payload.message);
//Only works for GCM
console.log('MESSAGE -> MSGCNT: ' + event.payload.msgcnt);
//Only works on Amazon Fire OS
console.log('MESSAGE -> TIME: ' + event.payload.timeStamp);
break;
case 'error':
console.log('ERROR -> MSG:' + event.msg);
break;
default:
console.log('EVENT -> Unknown, an event was received and we do not know what it is');
break;
}
};
return {
register: function () {
var q = $q.defer();
if(ionic.Platform.isAndroid()){
pushNotification.register(
successHandler,
errorHandler,
{
"senderID":"346007849782",
"ecb":"window.onNotificationGCM"
}
);
}else{
pushNotification.register(
tokenHandler,
errorHandler,
{
"badge":"true",
"sound":"true",
"alert":"true",
"ecb":"window.onNotificationAPN"
}
);
}
return q.promise;
}
}
update. Eventually my server spit back this: TypeError: Cannot read property 'processIncomingMessage' of undefined
It seems my google ID was not working. I created a new one and now it's sending push requests.

Is there any way for sending push notifications without appcelaretor cloud services?

I already know how to send push notifications in Titanium with Alloy, the way I do is:
// Require the module
var CloudPush = require('ti.cloudpush');
var deviceToken = null;
// Initialize the module
CloudPush.retrieveDeviceToken({
success: deviceTokenSuccess,
error: deviceTokenError
});
// Enable push notifications for this device
// Save the device token for subsequent API calls
function deviceTokenSuccess(e) {
deviceToken = e.deviceToken;
// alert("--->" + deviceToken);
subscribeToChannel();
}
function deviceTokenError(e) {
alert('Failed to register for push notifications! ' + e.error);
}
// Process incoming push notifications
CloudPush.addEventListener('callback', function (evt) {
alert("Notification received: " + evt.payload);
});
// For this example to work, you need to get the device token. See the previous section.
// You also need an ACS user account.
// Require in the Cloud module
var Cloud = require("ti.cloud");
function loginUser(){
// Log in to ACS
Cloud.Users.login({
login: 'example',
password: 'example'
}, function (e) {
if (e.success) {
alert('Login successful');
} else {
alert('Error:\n' +
((e.error && e.message) || JSON.stringify(e)));
}
});
}
function subscribeToChannel(){
// Subscribe the user and device to the 'test' channel
// Specify the push type as either 'android' for Android or 'ios' for iOS
// Check if logged in:
Cloud.PushNotifications.subscribe({
channel: 'test',
//device_token: 'APA91bHRjGoZLCYKwn-XcCtNLETuf-KRKfT4sMgVE4KgXQgInYfZuYTNrZC7FUMugLs0idzzqtLytrvVJjVzYBzQoc7Q81hEerq0O2vww_tV8mACuUfAi0JRvs7LoufnQZpYLZrb_1rlUsIOEMsPxDs9b_pIRJF5rw',
device_token:deviceToken,
type: Ti.Platform.name == 'android' ? 'android' : 'ios'
}, function (e) {
if (e.success) {
alert('Subscribed');
} else {
alert('Error:\n' +
((e.error && e.message) || JSON.stringify(e)));
}
});
}
function unsubscribeToChannel (){
// Unsubscribes the user and device from the 'test' channel
Cloud.PushNotifications.unsubscribe({
channel: 'test',
device_token: deviceToken
}, function (e) {
if (e.success) {
alert('Unsubscribed');
} else {
alert('Error:\n' +
((e.error && e.message) || JSON.stringify(e)));
}
});
}
loginUser();
However this way is only for sending push notification through https://cloud.appcelerator.com/ such a manually because it is needed you write the alert and push the button in that backend site.
So my question: Is there any way for sending push notification in Titanium from an own server in an "automatically" way?
Thanks in advance for any help.
Yes, it is possible.
How to obtain a device token for push notifications is described in the Titanium docs, here.
To send notifications you have to send the token to your server. The server then sends your notification to Apple Push Notification Services (APNS). See Apple docs. That's not "automatic" but it's a simple task for PHP or any other language - you can find a lot of scripts.
You can also schedule local notifications which might come in handy depending on your case.

Unable to receive Push notifications to Notifications Tray on Appcelerator Android

I have been trying to get Push notifications working for an android application. When the app is focussed, the push is received just fine. However, when the application is in the background, i see an error in the log.
My code is -
var CloudPush = require('ti.cloudpush');
CloudPush.retrieveDeviceToken({
success: function deviceTokenSuccess(e) {
console.log('Device Token: ' + e.deviceToken);
token = e.deviceToken;
that.token=token;
},
error: function deviceTokenError(e) {
console.log('Token Error: ' + e.error);
}
});
CloudPush.debug = true;
CloudPush.focusAppOnPush = false;
CloudPush.enabled = true;
// CloudPush.showAppOnTrayClick = false;
CloudPush.showTrayNotification = true;
// CloudPush.singleCallback = true;
CloudPush.addEventListener('callback', function(evt){
alert('A push notification was received!');
console.log('A push notification was received!' + JSON.stringify(evt));
});
CloudPush.addEventListener('trayClickLaunchedApp', function(evt){
alert('A push notification was received - onLaunched');
console.log('A push notification was received!' + JSON.stringify(evt));
});
CloudPush.addEventListener('trayClickFocusedApp', function(evt){
alert('A push notification was received - onFocused');
console.log('A push notification was received!' + JSON.stringify(evt));
});
and the error i am receiving is -
07-18 14:19:44.853: E/TiApplication(25319): (main) [9,46101] Sending event: exception on thread: main msg:java.lang.RuntimeException: Unable to start receiver ti.cloudpush.GCMReceiver: java.lang.NullPointerException; Titanium 3.2.3,2014/04/22 10:17,b958a70
07-18 14:19:44.853: E/TiApplication(25319): java.lang.RuntimeException: Unable to start receiver ti.cloudpush.GCMReceiver: java.lang.NullPointerException
Any thoughts on how i could work this out is highly appreciated.
Im using Titanium SDK - 3.2.3 GA.

Resources