I have a messaging app built using the Ionic framework (on cordova). I plan on building this for android, and I'd like a way to send and recieve push notifications from the app using javascript/ionic.
Are there any good tutorials out there on how to go about setting something like this up?
There is example application made available by Holly Schinsky. The core of it is the usage of PushPlugin which is the standard method to handle push notifications on Cordova. There is quite extensive tutorial provided for this subject on their documentation on that GitHub repository. The main method is pushNotification.register which registers the device to listen for push notifications.
If you instead need to trigger notification locally, you might want to take a look at Local notification plugin instead. With it you can add notifications to be shown on the device without the need for external services to send the push notifications.
Use this plugin https://github.com/phonegap-build/PushPlugin.
Android devices receive push notifications through the Google Cloud Messaging (GCM) service, whereas iOS devices receive them from the Apple Push Notifications (APN) Service.
The way the notifications are received (by sound, alert etc) is a combination of the options set in the application code upon registration as well as the user’s device settings for notifications.
If you want more specific follow below tutorial :
http://devgirl.org/2013/07/17/tutorial-implement-push-notifications-in-your-phonegap-application/
ngCordova has a plugin that supports Push Notifications. It has sample code for iOS and Android. Check it out: http://ngcordova.com/docs/plugins/pushNotifications/
The latest phonegap-plugin-push allows you to register and receive push notifications in your ionic apps. It is maintained at the following Github link:
https://github.com/phonegap/phonegap-plugin-push
Installation:
cordova plugin add https://github.com/phonegap/phonegap-plugin-push --variable SENDER_ID="XXXXXXX"
Where the XXXXXXX in SENDER_ID="XXXXXXX" maps to the project number in the Google Developer Console. To find the project number login to the Google Developer Console, select your project and click the menu item in the screen shot below to display your project number.
If you are not creating an Android application you can put in anything for this value.
Note: You may need to specify the SENDER_ID variable in your package.json.
"cordovaPlugins": [
{
"variables": {
"SENDER_ID": "XXXXXXX"
},
"locator": "phonegap-plugin-push"
}
]
Note: You need to specify the SENDER_ID variable in your config.xml if you plan on installing/restoring plugins using the prepare method. The prepare method will skip installing the plugin otherwise.
<plugin name="phonegap-plugin-push" spec="1.6.0">
<param name="SENDER_ID" value="XXXXXXX" />
</plugin>
After installation you can now add code below to your main javascript file to register and receive push notifications:
$ionicPlatform.ready(function () {
var push = PushNotification.init({
android: {
senderID: "XXXXXXX"//, //project token number (12 digit) from https://console.developers.google.com
// forceShow: "true", //force show push notification when app is in foreground on Android only.
},
browser: {
pushServiceURL: 'http://push.api.phonegap.com/v1/push'
},
ios: {
/*senderID: "XXXXXXX",*/ //If using GCM for ios, project token number (12 digit) from https://console.developers.google.com
/*gcmSandbox: 'true',*/ //If using GCM for ios
alert: 'true',
badge: 'true',
sound: 'true',
},
windows: {}
});
PushNotification.hasPermission(function (permissionResult) {
if (permissionResult.isEnabled) {
$log.debug("has permission for push notification");
/*Register device with GCM/APNs*/
push.on('registration', function (data) {
// data.registrationId
$log.debug("data.registrationId: " + data.registrationId);
});
push.on('notification', function (data) {
// data.message,
// data.title,
// data.count,
// data.sound,
// data.image,
// data.additionalData
$log.debug(JSON.stringify(data));
});
push.on('error', function (e) {
// e.message
$log.debug("e.message: " + e.message);
//alert(e.message);
});
}
});
}
}
Related
Has anyone actually used FCM - FireBase Cloud Messaging to create device push notifications with interactive action buttons that runs when the app is is background/closed?
The goal is for the user to be able to react to the notification like WhatsApp, Messenger...
The app is cordova so anyone with experience on that would be great.
I have all the FCM setup already done and the backend working.
I already can trigger a simple notification "title+body+icon/message"
According to FCM, the payload can contain the notification section, where the OS will handle the notifications, but nothing is said about it being able to contain buttons. (So it is not that interesting).
However it's possible to use the "data" section with the values key pairs that are sent to the app to generate a local notification with the buttons, on the onMessage callback.
[UPDATE]
The push service with data does not trigger the app to create the local notification if the app was swiped (some brands kill the app when swiped from recent apps - stopping javascript execution). Conclusion: For the FCM data payload message to work, must capture the push broadcast message event (native side) with a service, and then create the notification generation (native way) with buttons based on that data payload. FCM does not support push notifications with buttons.
import { getMessaging, getToken, onMessage } from "firebase/messaging";
import { getDevice } from "framework7/lite-bundle";
function setupPushNotification(getTokenCallBack,onMessageCallBack) {
const device = getDevice();
if (device.cordova) {
FirebasePlugin.getToken((token) => getTokenCallBack(token));
FirebasePlugin.onMessageReceived((message) => {
if (message) {
onMessageCallBack && onMessageCallBack(message);
}
},function(error){
console.error(error);
});
}
}
And then to setup the whole process, creating a local notification object with buttons previously defined:
cordova.plugins.notification.local.addActionGroup('yes-no', [
{ id: 'yes', title: 'Yes', foreground: false },
{ id: 'no', title: 'No', foreground: false }
])
setupPushNotification((deviceToken)=>{
//update device token on backend database
},
(message)=>{
//This is the onMessageReceived message
//Create a local notification for exaple using the local notification cordova plugin
cordova.plugins.notification.local.schedule({
title: "Test Title",
text: "Test Body",
actionGroupId: 'yes-no',
})
})
I'm using these cordova plugins
"cordova-plugin-local-notification": "^0.9.0-beta.2",
"cordova-plugin-firebasex": "^14.2.1"
You can do almost anything with cordova, that any native app does.
Ever tried cordova-plugin-firebase-messaging? I have been able to add a chat reply text box with send button in the notifications.
you can also refer to How to add action buttons to ionic push notifications?
I am facing an issue extremely similar to this one.
I am using Expo (SDK38) with the Managed Workflow
I am creating standalone APK builds with Turtle CLI on CI
I have an FCM project working almost perfectly with the standalone app. By almost perfectly I mean:
That I am successfully obtaining the device FCM token with the following code:
import { Notifications } from 'expo';
await Notifications.getDevicePushTokenAsync(); // Gives the token successfully
That I am sending a push notification when running the following NodeJS script, but:
const admin = require('firebase-admin');
admin.initializeApp({
credential: require('./my-credentials.json'),
databaseURL: 'https://MY_URL_HERE'
});
admin.messaging.send({
notification: { title: 'Foo', body: 'Bar' },
android: { ttl: 86400 },
token: 'THE_FCM_TOKEN_HERE'
});
[Minor issue 1] The device does not show any notification if the app is in foreground;
[Minor issue 2] The device shows the notification duplicated if the app is not in foreground.
I've mentioned the minor issues above for completeness, but the main problem I am facing now is that my app just won't notice that the notification arrived. The listener does not fire.
I tried both the Legacy Notifications Module and the New Notifications Module:
// Attempt using Legacy Notifications
// https://docs.expo.io/versions/v38.0.0/sdk/legacy-notifications/
import { Notifications as LegacyNotificationsModule } from 'expo';
// Attempt using New Notifications Module
// https://docs.expo.io/versions/v38.0.0/sdk/notifications/
import * as NewNotificationsModule from 'expo-notifications';
LegacyNotificationsModule.addListener(() => {
// Make any UI change just for we to see it happening
});
NewNotificationsModule.addNotificationReceivedListener(() => {
// Make any UI change just for we to see it happening
});
// I also tried commenting and uncommenting the code below
NewNotificationsModule.setNotificationHandler({
handleNotification: async () => ({
shouldShowAlert: true,
shouldPlaySound: false,
shouldSetBadge: false,
}),
});
Recall that, like in the similar issue I linked above, I am not using Expo notification tokens (of the form ExponentPushToken[xxxxxx]). I am using standard FCM tokens obtained via Notifications.getDevicePushTokenAsync().
How can I make this work?
I finally figured it out.
I've sent a PR to Expo to improve the documentation on this.
In short, quoting my comment on GitHub:
For the app to properly react to the notification, it must come with an extra special field called experienceId. I couldn't find a way to send this field through Firebase Console interface for sending test messages; instead I made it work performing a HTTP POST call with:
Headers:
Authorization: key=${FIREBASE_SERVER_KEY_TOKEN} (obtained in my Firebase project Settings > Cloud Messaging)
Content-Type: application/json
Body:
{
"to": "<DEVICE_PUSH_NOTIFICATION_TOKEN>",
"priority": "normal",
"data": {
"experienceId": "#anonymous/my-project-slug",
"title": "Hello",
"message": "World"
}
}
A key information that wasn't documented is that, for people like me that do not have an expo account (and are building everything independently of expo), the experience ID should start with #anonymous. Full credits for #awinograd in GitHub for figuring this out.
I am using phonegap-plugin-push with Android. Although I'm successful in registering the device, I cannot successfully deliver a notification using the registrationId returned by the plugin.
var push = PushNotification.init({
android: {
senderID: "XXXXXXXXXXXX"
}
});
push.on('registration', function (data) {
alert('registrationId: ' + data.registrationId);
});
The alert upon registration reads registrationId: dYeoRp-FIWc:APA91bExJIUVGgpqOh8NNRJ7Ua9vHun7ECN8JWBisFTzrxRYbC1C4cjEpnNsmxzCd7f0o8Hu6Fhp-nrQa5Efw95vtduJKi_o9H2NxeOJUCSX10z48sgDxWmHU7LVbOBa-vZjZVwouhc9.
An attempted push returns the following:
{"multicast_id":6855504054873897650,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}
What are you using to send the push notification? Whatever tool you're using may not like the special characters in the registrationId.
I am using parse-push plugin with Ionic to send push notification to android devices. On the parse dashboard the notification is shown as sent but notification is not received on the device.
This is the parse-push plugin I use-
cordova plugin add https://github.com/grrrian/phonegap-parse-plugin --variable APP_ID=<appId> --variable CLIENT_KEY=<clientKey>
This is my code in app.js-
window.parsePlugin.initialize("<adppId>", "<clientKey>", function() {
console.log('Parse initialized successfully.');
window.parsePlugin.subscribe('DefaultChannel', function() {
console.log('Successfully subscribed to DefaultChannel.');
window.parsePlugin.getInstallationId(function(id) {
// update the view to show that we have the install ID
console.log('Retrieved install id: ' + id);
}, function(e) {
console.log('Failure to retrieve install id.');
});
}, function(e) {
console.log('Failed trying to subscribe to DefaultChannel.');
});
}, function(e) {
console.log('Failure to initialize Parse.');
});
The device is registered as an installation object with the channel subscribed correctly as mentioned. Still the push-notification is not delivered.
Any one experienced this or knows how this can be solved?
Do you get an deviceToken registered in the Parse dashboard for this device?
I found bugs like this in some of the versions of phonegap-parse-plugin . Try a different fork like:
https://github.com/avivais/phonegap-parse-plugin or
https://github.com/bal200/phonegap-parse-plugin
Also, have you followed the Android Quirks section at the bottom of the Readme?
I was able to solve this by doing the following:
Delete the ionic plugin for push-notification (I had added it to try the ionic-push service) & Delete the parse-push plugin too.
Add the parse-push plugin again.
And this worked like a charm! I think the ionic-push plugin conflicts with the parse-push plugin I was using. Need to check their respective sources to figure out where exactly the conflict is but for now I have push notifications from parse working fine.
I am trying to implement Urban Airship in an Android Phone Gap application. I am using the Urban Airship Phone Gap plugin found on github. I know Urban Airship is successfully registering the device because:
It is telling me in LogCat
The device is showing up in my Urban Airship devices and I am able to push to it
I am also able to hook into the urbanairship.push event like so:
document.addEventListener("urbanairship.push", handleIncomingPush, false)
function handleIncomingPush(event) {
if(event.message) {
console.log("Incoming push: " + event.message)
} else {
console.log("No incoming message")
}
}
For some reason, however, the urbanairship.registration event is not firing. Here is my code:
document.addEventListener("urbanairship.registration", onRegistration, false)
function onRegistration(event) {
if (!event.error) {
console.log("Reg Success: " + event.pushID)
} else {
console.log('push registration error: ' + event.error)
}
}
I need this to fire so I can save the device's APID on my backend. Both of these are inside my onDeviceReady callback.
It appears the plugin is not very compatible with Cordova 3.0.0. I upgraded to Cordova 3.1.0 (cordova-3.1.0.jar) and changed my Urban Airship app to production instead of development and it worked.
I looked at UA's source code for their PhoneGap Push plugin and it has a function that can retrieve your APID.
Use this below after deviceready has fired to retreive your APID -
PushNotification.enablePush(function() {
console.log('push has been enabled');
PushNotification.getPushID(function(apid) {
console.log('got push apid, apid: ' + apid);
});
});
I know this can certainly help anyone seeking this out in the future. This is working great for me on Android, I'll soon be testing on iOS.
You can enable push automatically on app launch like this via the root config.xml -
<!-- Enable push when the application launches (instead of waiting for enablePush js call). Defaults to false -->
<preference name="com.urbanairship.enable_push_onlaunch" value="true | false" />