Cordova PushNotification onNotificationGCM is not called - javascript

I am doing pushnotification for both Android/IOS.
I have used a cordova push-plugin https://github.com/phonegap-build/PushPlugin, it seems to work great.
Info : I'm on a AngularJS project.
In my NotificationHelper factory i have this init method:
helper.init = function() {
// Instanciate push plugin notification
var pushNotification = window.plugins.pushNotification;
var errorHandler = function(error) {
logger.debug('errorHandler = ' + error);
};
if ($rootScope.isAndroid()) {
var senderId = CONFIG.NOTIFICATION_ANDROID_SENDER_ID;
pushNotification.register(function(result) {
logger.debug('successHandler = ' + result);
}, errorHandler, {
'senderID' : senderId,
'ecb' : 'onNotificationGCM'
});
}
};
I also defined those methods on mains.js :
var onNotificationGCM = function(event) {
// call back to web service in Angular.
var elem = angular.element(document.querySelector('[ng-app]'));
var injector = elem.injector();
var service = injector.get('NotificationHelper');
service.onNotificationGCM(event);
};
It's a trick to call angularJS factory from main javascript.
'onNotificationGCM' call the 'NotificationHelper.onNotificationGCM' method :
helper.onNotificationGCM = function(e) {
switch (e.event) {
case 'message':
// Notification happened while app was in the foreground
if (e.foreground) {
logger.debug('[notification] [message] Foreground : ' + JSON.stringify(e));
} else { // Notification touched in the notification tray
logger.debug('[notification] [message] Background : ' + JSON.stringify(e));
if (e.coldstart) {
// App was not running and user clicked on notification
} else {
// App was running and user clicked on notification
}
}
decriptPayloadNotification(e.payload);
break;
case 'registered':
logger.debug('[notification] [registered] : ' + JSON.stringify(e));
if (e.regid.length > 0) {
registerUser(e.regid, 'gcm');
}
break;
case 'error':
logger.debug('[notification] [error] : ' + JSON.stringify(e));
break;
default:
logger.debug('[notification] [default] : Unknown, an event was received and we do not know what it is : ' + JSON.stringify(e));
break;
}
};
During the first use, everything work good :
'Registered' event is received
Notifications are received
When i'm on foreground I receive 'message' event :
NotificationHelper: [notification] [message] Foreground : {"event":"message","from":"847593779913","message":"Agenêts 23/03 10h\r\n","collapse_key":"do_not_collapse","foreground":true,"payload":{"lt":"school","lv":"E1154","notId":"35429","title":"Agenêts le 23/03/2015","message":"Agenêts 23/03 10h\r\n"}}
When i'm on background, if i receive notif and touche it on notification tray, I receive 'message' event :
NotificationHelper: [notification] [message] Background : {"event":"message","from":"847593779913","message":"la piscine sera fermée 1 journée pour raison technique","coldstart":false,"collapse_key":"do_not_collapse","foreground":false,"payload":{"lt":"swimming pool","lv":"E114","notId":"29869","title":"23/04/2015 fermeture de la piscine","message":"la piscine sera fermée 1 journée pour raison technique"}}
BUT, if i kill my app, everything stop to work.
If i restart app, i will not receive anymore 'message'event and 'onNotificationGCM' will not be called.
I founded some articles speaking about this problem, but without success :
Stackoverflow : Phonegap PushNotification to open a specific app page
Does anyone has an idea about this problem ?

If you are using node-gcm as push notification server side I hope this might help for your question:
things to check:
use adb logcat from console and check your device logs to see if your device receives any notification (you should see some logs from gcmservices if you receive). I believe you should see some logs because otherwise you probably wouldn't get any notification when the app is on foreground either.
check if you add "title" and "message" keys on your message data (this draw me crazy before)
check if delayWhileIdle parameter is false
sample message variable and method i am using is below:
var pushAndroidSender = new gcm.Sender('Your GoogleApi Server Key Here');
var message = new gcm.Message({
collapseKey: 'demo',
delayWhileIdle: false,
timeToLive: 3,
data: {
"message":"What's up honey?",
"title":"Come on"
}
});
pushAndroidSender.send(message, registrationIds, function(err, result) {
if (err) {
console.error("this is an error: " + err);
} else {
console.log("this is a successful result:" + result);
}
});

I was asking myself why it worked correctly the first time and not the following times...and i had this idea :
maybe callback function is subscribed to plugin first time but not the next times.
And this is exactly the source of my problem. I call "pushNotification.register" only one time to init plugin and get ids...
But the next time I launch app, i don't instanciate again the plugin, so pushplugin don't know which method to call in callback request.
So answer is : Call "pushNotification.register" in each application launch !
In my code, i have to call method below on each "deviceready" event :
helper.init = function() {
// Instanciate push plugin notification
var pushNotification = window.plugins.pushNotification;
var errorHandler = function(error) {
logger.debug('errorHandler = ' + error);
};
if ($rootScope.isAndroid()) {
var senderId = CONFIG.NOTIFICATION_ANDROID_SENDER_ID;
pushNotification.register(function(result) {
logger.debug('successHandler = ' + result);
}, errorHandler, {
'senderID' : senderId,
'ecb' : 'onNotificationGCM'
});
}
};

Related

How a ServiceWorker can trigger a refresh/reload by a push to all subscribers?

here is the process i would like to dev :
A page with a serviceWorker
UserA and UserB accept notification from this page only
Behavior :
if a user modify the page, the other users are notified (already working mobile/desktop)
Now i would like that if userA modify the page :
If the page was already opened on UserB browser, it refresh automaticly
If the userB click on notification : the page is refreshed
but it seems that :
ServiceWorker can't call "reload"
a trick such a setInterval to check last update doesn't work on android chrome (certainly for bandwidth?)
so my question is :
is it a way to let the server push an serviceWorker event to call a reload on each subscribers even if the page is already opened on their browser ?
In other word : On page update, serviceWorker order subscriber to reload
such serviceworker code fail :
if (client.url == self.registration.scope && 'focus' in client) {
client.postMessage('reload'); // DOESN'T WORK
return client.focus();
}
Failing code on android/chrome for setinterval :
setInterval(async function(){
const response = await fetch('/lastupdatetimestamp', {
method: 'get',
headers: { 'Content-Type': 'application/json' }
});
const json= await response.json();
if(LASTUP<json.up.lastdate){
window.location.reload()
LASTUP=json.up.lastdate
}
}, 30000);
Any idea ?
I finally founded a first step :
server send push -> serviceworker show notification -> click on notification -> goes open window and reload
in the serviceWorker.js
self.addEventListener('push', function (event) { ... }
self.addEventListener('notificationclick', async function(event) {
event.notification.close();
await event.waitUntil(clients.matchAll({
type: "window",
includeUncontrolled: true
}).then(function(clientList) {
for (var i = 0; i < clientList.length; i++) {
var client = clientList[i];
if (client.url == self.registration.scope && 'focus' in client) { //
client.postMessage('reload'); // <= TRIGGER 'RELOAD' EVENT HERE
return client.focus();
}
}
if (clients.openWindow) {
return clients.openWindow(self.registration.scope);
}
}));
});
in the app.js
function initPostMessageListener() {
console.log("event listener message")
navigator.serviceWorker.addEventListener('message', function(e) {
var message = e.data;
console.log("ON A UN MESSAGE")
switch (message) {
case 'reload':
window.location.reload(true);
break;
default:
console.warn("Message '" + message + "' not handled.");
break;
}
});
}
call initPostMessageListener() in the app.js where the SW is registered
So the SW.js handle the notificationClick then open the browser window if exist and reload it

WebRTC video call and IONIC, call when app runs in background

I made an application using twilio, webRTC and ionic, and the video call is working. However, is it possible to make the video call when the app runs in background? I couldn't come up with a solution with ionic.
I created a landing page upon login which has all the token grant and initialization of twilio so that once a user logs in. It is already on listening mode. Then, i handled the opening of push to actually just redirect to that particular landing page. In my case, the landing page is app.onlineUsers
var notificationOpenedCallback = function(jsonData) {
console.log('notificationOpenedCallback: ' + JSON.stringify(jsonData.action));
if (jsonData.action) {
if (jsonData.action.actionID == "IdAccept") {
$state.go('app.onlineUsers');
//custom code executes
} else if (jsonData.action.actionID == "IdReject") {
alert('rejected');
}
}
};
window.plugins.OneSignal.getIds(function(ids) {
// alert(ids);
did = ids.userId;
$sessionStorage.DID = did;
$localStorage.DID = did;
// alert(" player_id: "+$localStorage.DID);
});
// TODO: Update with your OneSignal AppId and googleProjectNumber before running.
window.plugins.OneSignal.startInit("appId", "googleProjectNumber")
.handleNotificationOpened(notificationOpenedCallback).handleNotificationReceived(function(jsonData) {
$state.go('app.onlineUsers');
// alert("Notification received:\n" + JSON.stringify(jsonData));
// console.log('Did I receive a notification: ' + JSON.stringify(jsonData));
}).inFocusDisplaying(window.plugins.OneSignal.OSInFocusDisplayOption.None).endInit();

How to open specific page in the app on clicking Push Notification?

I am working on an Android app using cordova and implemented a push notification system using the cordova $PushPlugin.
My PushPlugin code (source):
module.run(function($rootScope,$cordovaPush) {
var androidConfig = {
"senderID": "replace_with_sender_id",
};
document.addEventListener("deviceready", function(){
$cordovaPush.register(androidConfig).then(function(result) {
// Success
}, function(err) {
// Error
})
$rootScope.$on('$cordovaPush:notificationReceived', function(event, notification) {
switch(notification.event) {
case 'registered':
if (notification.regid.length > 0 ) {
alert('registration ID = ' + notification.regid);
}
break;
case 'message':
// this is the actual push notification. its format depends on the data model from the push server
alert('message = ' + notification.message + ' msgCount = ' + notification.msgcnt);
break;
case 'error':
alert('GCM error = ' + notification.msg);
break;
default:
alert('An unknown GCM event has occurred');
break;
}
});
// WARNING: dangerous to unregister (results in loss of tokenID)
$cordovaPush.unregister(options).then(function(result) {
// Success!
}, function(err) {
// Error
})
}, false);
});
On clicking the push notification received, I want to redirect the user to a specified page in my app. I referred this(based on phonegap pushplugin) but could not figure out a solution. Any help will be appreciated.
This is a simple solution without using any angular routes.
case 'message':
if (notification.foreground === false){
window.location = '#/abc';
window.location.reload();
}
If you check structure of object notification, you will see that there is an attribute foreground, which will be false when you come to app from clicking notification. You can use that to put your logic
case 'message':
if(notification.foreground === false){
//add logic for navigation to your specific page i.e $state.go('myPage')
}

Can’t get push notifications in Android to work using ngCordova

I'm having a tough time getting push notifications (using the ngCordova plugin) to work. I have followed their sample code exactly as is documented on the site: http://ngcordova.com/docs/plugins/pushNotifications/
(the only difference is that I don't have a deviceready listener, instead, my code is inside the ionicPlatform.ready listener.)
Here is my code:
angular.module('myApp', ['ionic', 'ngCordova'])
.run(function($ionicPlatform, $rootScope, $state, $cordovaPush) {
$ionicPlatform.ready(function() {
var config = {
"senderID": "myID100001000"
};
$cordovaPush.register(config).then(function(result) {
alert(result);
}, function(err) {
alert(err);
})
});
$rootScope.$on('$cordovaPush:notificationReceived', function(event, notification) {
switch(notification.event) {
case 'registered':
if (notification.regid.length > 0 ) {
alert('registration ID = ' + notification.regid);
}
break;
default:
alert('An unknown GCM event has occurred');
break;
}
});
})
When my app starts I do get the "OK" alert, so I know it successfully goes through the $cordovaPush.register call. However, I was expecting to get a "registered" notification event, right after, but I never get notified.
Any help would be appreciated.
The solution is in the comments but this needs a proper answer.
First of all, the register callback always returns OK as long as you pass a senderID, but if the $cordovaPush:notificationReceived event is never called (it may take a few seconds), this ID is probably wrong.
You must use the Project Number, not the Project ID.
To get the number, go to the API Console, select the project and you'll be on the Overview page. On top of this page, you'll see something like this:
Project ID: your-project-id Project Number: 0123456789
Just copy and use the project number and everything should work.
I have suffered with this a lot and I have found out, that there are in fact two versions of the cordova push plugin currently:
https://github.com/phonegap-build/PushPlugin (deprecated)
https://github.com/phonegap/phonegap-plugin-push (new one)
Both are supported by ngCordova, but only the deprecated version is documented.
The deprecated version is $cordovaPush
and the newer one is $cordovaPushV5, and they have completely different methods.
For me the problem was that I downloaded the cordova-plugin-push and tried to implement it with the old documentation on ngCordova site.
The code is:
/*
* Non deprecated version of Push notification events
*/
function registerV5() {
$ionicLoading.show({
template: '<ion-spinner></ion-spinner>'
});
if (ionic.Platform.is('browser')) {
alert("You are running on broswer, please switch to your device. Otherwise you won't get notifications");
$ionicLoading.hide();
return;
}
/**
* Configuration doc:
* https://github.com/phonegap/phonegap-plugin-push/blob/master/docs/API.md#pushnotificationinitoptions
*/
var GCM_PROJECT_ID = 'xxxxxx';
$cordovaPushV5.initialize({
"android": {
"clearNotifications": false,
"senderID" : GCM_PROJECT_ID
}
});
$cordovaPushV5.register().then(function (deviceToken) {
console.log("Successfully registered", deviceToken);
$scope.data.deviceToken = deviceToken;
// Below code required to configure $cordovaPushV5 notifications emitter.
// Don't pass function it's not handler.
$cordovaPushV5.onNotification();
$cordovaPushV5.onError();
$ionicLoading.hide();
}, function (error) {
console.log("Failed to registered");
console.log("error object : ", error);
$ionicLoading.hide();
});
}
$rootScope.$on('$cordovaPushV5:notificationReceived', function(event, data) {
console.log("notification received");
console.log("data object: ", data);
var foreground = data.additionalData.foreground || false;
var threadID = data.additionalData.payload.threadID || '';
var group = data.additionalData.payload.group || false;
if (foreground) {
// Do something if the app is in foreground while receiving to push - handle in app push handling
console.log('Receive notification in foreground');
} else {
// Handle push messages while app is in background or not started
console.log('Receive notification in background');
// Open FB messanger app when user clicks notification UI when app is in background.
if (typeof data.additionalData.coldstart != "undefined" && data.additionalData.coldstart == false)
if (!group)
// Open FB Messenger of specific user chat window
window.open('fb-messenger://user/' + threadID, '_system', 'location=no');
else
// Open FB Messenger of specific group chat window
window.open('fb-messenger://groupthreadfbid/' + threadID, '_system', 'location=no');
}
});
$rootScope.$on('$cordovaPushV5:errorOccurred', function(event, error) {
console.log("notification error occured");
console.log("event object: ", event);
console.log("error object: ", error);
});
More on this github article: https://github.com/driftyco/ng-cordova/issues/1125 (code from here) and in this article: https://github.com/yafraorg/yafra/wiki/Blog-Ionic-PushV5

the event fired by server

My server is firing an event to client2 on some request by client1.The fired event is captured correctly by client2.
See the below code:
'experimentService.experimentPermissionChangedByOwner subscribe': function(eventName, event){
if(this.resource.id == event.eventData.resource) {
if (event.eventData.permissionType == "unshare") {
message = this.resource.name +" has been unshared by the owner: "+event.eventData.ownerUsername+". "+messagePart2;
this.openWorkspaceObject({id: event.eventData.dashboardId, namespace: "bjkbb", type: "jhvhhkk" });
}
else {
message = "Owner: "+event.eventData.ownerUsername+" changed permission of "+ this.resource.name +" to "+ event.eventData.permissionType +". ";
if (event.eventData.permissionType == "view") {
message += messagePart2;
}
this.publish("elements.atlas.resource-page-modified", this.resource);
}
this.openDialog({
dialogClass: elements.AlertCollaborators,
message: message
});
}
this.publish("event.ack", {eventId: event.id});
},
The above code is going to create a small dialog box with a message. Now the problem is on refreshing the browser, it again goes into the subscribe function. I dnt know how to handle this? Moroever after putting debug points I saw that it does not go into publish for this method. Then how does the subcribe capture it again??

Categories