I'm implementing push notifications in a Ionic 2 app for Android. For this, I'm using the following function:
registerPush() {
this.push.register().then((t: PushToken) => {
return this.push.saveToken(t, {ignore_user: false});
}).then((t: PushToken) => {
this.push.rx.notification().subscribe(msg => {
// execute some code
});
});
}
With this, I'm able to receive push notifications sent from server. While the app is in foreground, the execute some code part is run without problems. While the app is in the background (I'm using the background plugin), the push notification is received, but when I click on it nothing happens.
I want to execute the notification code in this situation too, and open the app when I click it. Is there any way to achieve this?
UPDATE
I've read the plugin documentation and changed the code accordingly:
registerPush() {
this.pushNotifications = Push.init({ android: { senderID: "xxxxxxxx" } });
this.pushNotifications.on('registration', data => {
// send token to server
});
this.pushNotifications.on('notification', data => {
// handle notification
});
}
With this, and with content-available set to 1 in the notification sent from server, the app executes the code whether I'm inside it or not.
However, I'm still not able to put it in foreground when I click the notification.
Related
I am developing a react-native messaging app with Expo. Every time a user receives a new message, I send a notification from my server.
Is there any way to not display the notification if the app is currently open?
Right now I am using this as soon as the notification is received:
Notifications.dismissNotificationAsync(notification.notificationId);
But there is a 0.5 second delay where the notification has time to appear in the tray and trigger a sound before it gets dismissed. I would like to not show it at all.
When a notification is received while the app is running, using setNotificationHandler you can set a callback that will decide whether the notification should be shown to the user or not.
Notifications.setNotificationHandler({
handleNotification: async () => ({
shouldShowAlert: true,
shouldPlaySound: false,
shouldSetBadge: false,
}),
});
When a notification is received, handleNotification is called with the incoming notification as an argument. The function should respond with a behavior object within 3 seconds, otherwise the notification will be discarded. If the notification is handled successfully, handleSuccess is called with the identifier of the notification, otherwise (or on timeout) handleError will be called.
The default behavior when the handler is not set or does not respond in time is not to show the notification.
If you don't use setNotificaitonHandler, the new notifications will not be displayed while the app is in foreground.
So you can simply set setNotificationHandler to null when your app is initialized.
Notifications.setNotificationHandler(null);
See Documentaition
The answer is yes to your question
Is there any way to not display the notification if the app is
currently open?
The default behavior of Notification in Expo is not to show notification if the App is in foreground. You must have implemented Notifications.setNotificationHandler similar to the following code -
// *** DON'T USE THE FOLLOWING CODE IF YOU DON'T WANT NOTIFICATION TO BE DISPLAYED
// WHILE THE APP IS IN FOREGROUND! ***
// --------------------------------------------------
// Sets the handler function responsible for deciding
// what to do with a notification that is received when the app is in foreground
/*
Notifications.setNotificationHandler({
handleNotification: async () => ({
shouldShowAlert: true,
shouldPlaySound: true,
shouldSetBadge: false,
}),
});
*/
If you don't use setNotificaitonHandler, the new notifications will not be displayed while the app is in foreground.
Use below code snippet. It works on press notification.
_handleNotification = async (notification) => {
const {origin} = notification;
if (origin === ‘selected’) {
this.setState({notification: notification});
}
//OR
if (AppState.currentState !== 'active') {
this.setState({notification: notification});
}
}
I assume you setup a simple FCM - Firebase cloud messaging
And use that to push messages to the client?
The official Expo guide has a section for receiving-push-notifications
This is the actual workflow of FCM (weird can be called as a common issue) that it'll handle the notifications by itself when the application is in the foreground.
The solution which i did for my project was to create a custom notification JSON rather than using their default template which won't be parsed by FCM.
{
"hello":" custom key and value",
"message":{
"SampleKey":"Sample data",
"data":{
"SampleKey" : "Sampledata",
"SampleKey2" : "great match!"},
}}
In console you can add your own custom JSON objects, and when you get the notification parse the notification by using these objects, then you will be able to override that issue.
You can also add a channel for the request to categorize your notifications
this.createNotificationListeners = firebase.notifications()
.onNotification((notification) => {
let{ hello,data,message} = notification;
});
I am using cordova plugin add phonegap-plugin-push plugin for push notification
In forground notification works fine.and i can handle event also.
When my app is in background then i got notification as well but on click of push notification my event is not fire.
I am using below code
$cordovaPushV5.initialize(options).then(function() {
// start listening for new notifications
$cordovaPushV5.onNotification();
// start listening for errors
$cordovaPushV5.onError();
// register to get registrationId
if (PNdeviceToken == null) //becuase registration will be done only the very first
{
$cordovaPushV5.register().then(function(registrationId) {
// save `registrationId` somewhere;
window.localStorage.setItem('PNdeviceToken', registrationId);
$rootScope.fcmToken = registrationId;
console.log(registrationId)
alert("first time registered id -- " + registrationId)
})
} else {
$rootScope.fcmToken = PNdeviceToken;
alert("already saved registered id -- " + $rootScope.fcmToken)
}
});
$rootScope.$on('$cordovaPushV5:notificationReceived', function(event, data) {
console.log(event)
console.log(data)
})
When i tap on background push notiction then $cordovaPushV5:notificationReceived event not fire, How can I solve this problem?
How can i handle background push notification event?
I had the Same issue and got it resolved it after 2 days of research.
Handling the notification events is same whether the app is in foreground or background.
We have to set "content-available" : "1" in the data field while pushing notifications. Else it wont call notificationReceived event if app is in background.
Also note this is not possible as of now through Google Firebase Console.
We have to send our custom payload messages (data or notification or both) seperately using any one of the firebase servers.
Detailed info can be found on the plugin's GitHub Docs Page on background notifications.
Quoting from there -
On Android if you want your on('notification') event handler* to be called when your app is in the background it is relatively simple.
First the JSON you send from GCM will need to include "content-available": "1". This will tell the push plugin to call your on('notification') event handler* no matter what other data is in the push notification.
*on('notification') event handler = $cordovaPushV5:notificationReceived event in your case.
See this answer for sending custom payload messages using PHP and NodeJS
I am developing an application using cordova and ibm mobile first 8 and wanted to integrate a push notification system.
I registre the device in the server and i can send the notification from the server to client app then the client app handle a received push notification by operating on its response object in the registered callback function :
var notificationReceived = function(message) {
alert(JSON.stringify(message));
};
Here is my issues :
alert issues
I don't want the alert to be displayed.
And I want that when I click on the notification A function is called.
how can i do this ? Please i need your help thanks .
In the code snippet you have in your question there is an alert. Remove the alert snippet and no alert dialog will be displayed...
You can then put there instead anything else you'd like, like logging the notification contents, or performing any other action, like calling a function.
var notificationReceived = function(message) {
myFunction();
};
function myFunction() {
...
}
I work in Ionic Application, where I need to open a specific page in the app when users tap on notification,
Code
push.on('notification', function(data) {
window.plugins.toast.showShortTop('You have received a new Application!');
window.location.hash = 'home/contactus';
});
Its work fine when an application start open first time. But the problem is that when application open and that time user get any notification application redirect to 'home/contactus' page every time.
Please Help.
Unfortunately, the push plugin raises the notification event when the notification is received and again when it's clicked.
Your best bet is to assign and track the ids of notifications sent to the app:
var receivedNotifications={};
push.on('notification', function(data) {
if(!receivedNotifications[id]){
receivedNotifications[id]=true;
return;
}
window.plugins.toast.showShortTop('You have received a new Application!');
window.location.hash = 'home/contactus';
});
Consider this scenario. I have an ionic / angular app and I am using the the ngcordova plugin for push notifications. Now let us say a push notification arrives when the app is in the background. User, views the notification in the App drawer and then clicks the notification for further information. I would like the user to navigate to a particular path using $location.path(). How can I tap into the notification click event?
Ok. Turns out that there is no need to tap into the notification click event.
You could check if the app is in foreground using:
notification.foreground
so, if
if(notification.foreground) {
//do something for the case where user is using the app.
$popup('A notification just arrived');
} else {
//do something for the case where user is not using the app.
$location.path('/tab/somepage');
}
I answered a similar question some days ago. Here's the link
What i did was when the notification arrives to the app i save some data from the playload to the localStorage and then in the resume event of the app i read this var from localStorage and change the state of the app and passing this var to the url i want.
When the app is in the background and receive the notification you can save the playload to the localStorage:
$rootScope.$on('$cordovaPush:notificationReceived', function(event, notification) {
if (ionic.Platform.isAndroid() && notification.event == 'message') {
var newsid=notification.payload.newsid;
if (typeof newsid != 'undefined') {
// save the newsid to read it later in the resume event
$window.localStorage.setItem('goafterpush',newsid);
}
}
});
And then in the resume event you can read the previous saved playload and use that data to change the state of the app and redirect to another route:
$ionicPlatform.on("resume",function(event){
// read the newsid saved previously when received the notification
var goafterpush=$window.localStorage.getItem('goafterpush');
if (goafterpush) {
$window.localStorage.removeItem('goafterpush');
$state.go('app.newsdetail',{id:goafterpush});
}
});
This can simply be done if you are using phonegap-plugin-push.
Refer the blog article from here.
push.on('notification', function(data) {
if(data.additionalData.foreground){
//Do stuff you want to do if app is running on foreground while push notification received
}else{
//Do stuff you want to do if the app is running on background while the push notification received
}
});