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')
}
Related
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();
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'
});
}
};
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
I have added in <gap:plugin name="com.phonegap.plugins.pushplugin" /> config.xml. When I run the app it shows alert "Callback Success! Result = OK" even when phone is not connected to internet then I press OK and nothing else happens.
onNotificationGCM event does not fire and so it never returns regid.
function showAlert(message, title) {
if (navigator.notification) {
navigator.notification.alert(message, null, title, 'OK');
} else {
alert(title ? (title + ": " + message) : message);
}
}
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
$(document).ready(function () {navigator.splashscreen.hide();});
try {
var pushNotification = window.plugins.pushNotification;
pushNotification.register(successHandler, errorHandler, {"senderID":"659859389520","ecb":"onNotificationGCM"});
} catch (ex) {
showAlert(ex, 'push error');
}
setTimeout(function() {
navigator.splashscreen.hide();
}, 3000);
}
function successHandler(result) {
showAlert('Callback Success! Result = '+result, "Success");
}
function errorHandler(error) {
showAlert(error, "Error");
}
function onNotificationGCM(e) {
switch( e.event )
{
case 'registered':
if ( e.regid.length > 0 )
{
console.log("Regid " + e.regid);
showAlert('registration id = '+e.regid);
}
break;
case 'message':
showAlert('message = '+e.message+' msgcnt = '+e.msgcnt, "Message");
break;
case 'error':
showAlert('GCM error = '+e.msg, "Error");
break;
default:
showAlert('An unknown GCM event has occurred', "Unknown Event");
break;
}
}
In the ADB log GCM is working absolutely fine. It is returning a regid perfectly but sendJavascript is not calling my onNotificationGCM function. And therefore it is not working. Why? What I am doing wrong here?
05-22 01:28:27.407: V/PushPlugin(21372): sendJavascript: javascript:onNotificationGCM({"regid":"APb91bG...Sqg4YP","event":"registered"})
Solved the issue. I was redirecting from index.html to another page before onNotificationGCM could be called. Therefore it was not being called at all.
To test I placed the redirection code inside onNotificationGCM and it works perfect.
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??