Hi this is a duplicate of the question at
Push Notifications in Ionic 2 with the Pub/Sub Model
i have already implemented push notifications following this article >
https://medium.com/#ankushaggarwal/push-notifications-in-ionic-2-658461108c59#.xvoeao59a
what i want is to be able to send notifications to users when some events take place in the app like chat or booking or new job post.
how to go further , this is my first app.
NOTE: code is almost exactly the same as the tutorial, Java has only been converted to Kotlin
This is my acutal ionic side code (on login page). The push.on('registration') will be fired when the user opens the app, the variable this.device_id will later (on succesfull login) be sent to my Kotlin REST API so I know the device_id and have coupled it to a user. This way you can send targeted push notifications.
If you send a push notification from Kotlin (code shown below, looks a bit like Java), the (always open, even opens after startup) connection to Google will send your device (defined by the device_id a message with the notification data (title, message, etc.) after which your device will recognize the senderID and match it to use your ionic application.
initializeApp() {
this.platform.ready().then(() => {
let push = Push.init({
android: {
senderID: "1234567890"
},
ios: {
alert: "true",
badge: false,
sound: "true"
},
windows: {}
});
//TODO - after login
push.on('registration', (data) => {
this.device_id = data.registrationId;
});
push.on('notification', (data) => {
console.log('message', data.message);
let self = this;
//if user using app and push notification comes
if (data.additionalData.foreground) {
// if application open, show popup
let confirmAlert = this.alertCtrl.create({
title: data.title,
message: data.message,
buttons: [{
text: 'Negeer',
role: 'cancel'
}, {
text: 'Bekijk',
handler: () => {
//TODO: Your logic here
this.navCtrl.setRoot(EventsPage, {message: data.message});
}
}]
});
confirmAlert.present();
} else {
//if user NOT using app and push notification comes
//TODO: Your logic on click of push notification directly
this.navCtrl.setRoot(EventsPage, {message: data.message});
console.log("Push notification clicked");
}
});
push.on('error', (e) => {
console.log(e.message);
});
});
}
Kotlin code (converted from the Java example, basically the same
package mycompany.rest.controller
import mycompany.rest.domain.User
import java.io.OutputStream
import java.net.HttpURLConnection
import java.net.URL
class PushNotification {
companion object {
val SERVER_KEY = "sOmE_w31rD_F1r3Ba5E-KEy";
#JvmStatic fun sendPush(user: User, message: String, title: String) {
if(user.deviceId != "unknown"){
val pushMessage = "{\"data\":{\"title\":\"" +
title +
"\",\"message\":\"" +
message +
"\"},\"to\":\"" +
user.deviceId +
"\"}";
val url: URL = URL("https://fcm.googleapis.com/fcm/send")
val conn: HttpURLConnection = url.openConnection() as HttpURLConnection
conn.setRequestProperty("Authorization", "key=" + SERVER_KEY)
conn.setRequestProperty("Content-Type", "application/json")
conn.setRequestMethod("POST")
conn.setDoOutput(true)
//send the message content
val outputStream: OutputStream = conn.getOutputStream()
outputStream.write(pushMessage.toByteArray())
println(conn.responseCode)
println(conn.responseMessage)
}else {
println("Nope, not executed")
}
}
#JvmStatic fun sendPush(users: List<User>, message: String, title: String) {
for(u in users) {
PushNotification.sendPush(u, message, title)
}
}
}
}
Then the method can be called as PushNotification.sendPush(user1, "Hello world!", "my title");
(btw realized you won't need to run the pushnotification from a server (localhost/external). You can just create a main class which sends it with your hardcoded deviceId for testing purposes.
Related
I’m using Kuzzle as backend for my realtime chat application.
What is the better approach to sending push notification when user is offline in a mobile chat app?
1. Using custom plugin hooks
// check for every message in chat
this.hooks = {
'document:afterCreate': (request) => {
if (request.input.resource.collection == 'messages') {
let message = request.input.body;
this.context.accessors.sdk.document.get('now', 'user_sessions', message.otherUserId).then((userSession) => {
if (!userSession._source.isOnline) {
userSession._source.devices.forEach(device => {
// send push notification
});
}
})
}
}
}
2. Subscription per user for all users after the Kuzzle server start-up
const app = new Backend('kuzzlebackend')
app.start()
.then(async () => {
// Application started
// Loops through all users and adds their subscriptions to Kuzzle
foreach(user in users) {
app.sdk.realtime.subscribe('now', 'messages', { ‘otherUserId' : user._id }, async (notification: Notification) => {
this.context.accessors.sdk.document.get('now', 'user_sessions', user._id).then((userSession) => {
if (!userSession._source.isOnline) {
userSession._source.devices.forEach(device => {
// send push notification
});
}
})
})
}
})
You should use the hook mechanism on the generic:document:afterWrite event to send notification to offline users when a new message is created.
This event will be triggered every time a document is written with one of the Document controller action, and for the m* action family it you will able to process documents in bulk instead of one by one.
Was hoping to achieve when OneSignal push notification was being opened would redirect to a certain page in the App. Following is my code to redirect to a page called positions but it didn't seem to work. When the push notification is opened, it still opens up the url in the InAppBrowser. Any idea what went wrong? Thanks in advance.
if (this.appConfig.Onesignal_Enable == true) {
this.oneSignal.startInit(this.appConfig.OneSignal_AppID, this.appConfig.GCM_SenderID);
this.oneSignal.handleNotificationReceived().subscribe(() => {
// do something when notification is received
});
this.oneSignal.handleNotificationOpened().subscribe((data) => {
// do something when a notification is opened
// the following two lines pass data I send with the push notification so the app knows what to open
let pushaction = data.notification.payload.additionalData.action;
let pushactionvalue = data.notification.payload.additionalData.actionvalue;
// this fires up the tab-switching
this.runNotificationAction(pushaction, pushactionvalue);
});
this.oneSignal.endInit();
}
runNotificationAction(pushaction, pushactionvalue){
// this is the data passed the the other page
let data = {"action": pushaction, "value:": pushactionvalue};
this.navCtrl.navigateForward('positions');
}
Hello I'm using v4 ionic too and I achieved this with this implementation on my project:
let self = this;
var notificationOpenedCallback = async function(jsonData) {
//I use info data previous saved, but you can use jsonData
switch (self.user.role) {
case "customer":
self.router.navigate(["history-customer"]);
break;
case "provider":
self.router.navigate(["history-provider"]);
}
};
window["plugins"].OneSignal.startInit(
"0*************7",
"1*********2"
)
.handleNotificationOpened(notificationOpenedCallback)
.endInit();
window["plugins"].OneSignal.setSubscription(true);
I use
let self = this
because startInit receive a callback so is necessary to do that, in your case I don't know if inside subscribe need also use "self" and I use Router to navigate between pages.
import { Router } from "#angular/router";
And on my app-routing.module.ts
{ path: 'history-provider', loadChildren: './pages/history-provider/history-provider.module#HistoryProviderPageModule' },
{ path: 'history-customer', loadChildren: './pages/history-customer/history-customer.module#HistoryCustomerPageModule' }
I am using OneSignal API for sending and receiving notifications with my Flutter app. And I don't know how to use the buttons that can be added to the notification to open my flutter app to a specific screen.
My use case of the API is to create a notification template that has a button on it and send it to my users. But I don't know how to set a listener on that button that will open my flutter app.
I am using onesignal-node package for my node server.
let firstNotification = new OneSignal.Notification({
template_id: "727f42a8-0b45-470e-ac9e-908f64af44ba",
include_external_user_ids: [_id]
});
myClient.sendNotification(firstNotification, function (err, httpResponse, data) {
if (err) {
return res.status(500).send(err);
} else {
console.log(data, httpResponse.statusCode);
return res.status(200).send("Notification sent to " + user);
}
});
This is the solution
buttons: [
OSActionButton(text: "text button 1", id: "id1"),
OSActionButton(text: "text button 2", id: "id2")
],
but i dont know how i set an event to the button =(
i created an app on dialogflow and deployed on google assistant,
it is working fine on both mobile assistant and google home, but the notification(daily update) is not working on google home mini device
well daily update working really fine in mobile device, and i didnt use any rich response like card and other thing which mini device doesnt support, then what is the possible reason?
Currently it is deployed home-notification-6b314 same google app is used for deployment of firebase function(as webhook), dialogflow app and and action on google
what should i do?
here is some code which i write on my webhook for reference:
// process.env.DEBUG = 'actions-on-google:*';
import * as functions from 'firebase-functions';
const { DialogflowApp } = require('actions-on-google');
const Actions = {
UNRECOGNIZED_DEEP_LINK: 'deeplink.unknown',
FINISH_UPDATE_SETUP: 'finish.update.setup',
};
const Parameters = {
CATEGORY: 'category',
UPDATE_INTENT: 'UPDATE_INTENT'
};
const DAILY_NOTIFICATION_ASKED = 'daily_notification_asked';
const PUSH_NOTIFICATION_ASKED = 'push_notification_asked';
export const webhook = functions.https.onRequest((request, response) => {
try {
const app = new DialogflowApp({ request, response });
console.log('Request headers: ' + JSON.stringify(request.headers));
console.log('Request body: ' + JSON.stringify(request.body));
// Map of action from Dialogflow to handling function
const actionMap = new Map();
actionMap.set(app.StandardIntents.CONFIGURE_UPDATES, configureUpdates);
actionMap.set(Actions.FINISH_UPDATE_SETUP, finishUpdateSetup);
actionMap.set("welcome", welcome);
actionMap.set("whatMissed", whatMissed);
actionMap.set("what_did_i_missed.what_did_i_missed-yes", whatMissed_yes);
app.handleRequest(actionMap);
} catch (e) {
console.log("catch error: ", e)
}
});
function welcome(app) {
app.ask(app.buildRichResponse()
.addSimpleResponse({
speech:
`<speak>
<s> Hi, I'm you medication assistant </s>
</speak>`
})
)
}
// Start opt-in flow for daily updates
function configureUpdates(app) {
console.log("====>> configure triggered1")
const intent = app.getArgument('UPDATE_INTENT');
console.log("##### INTENT: ", intent);
const category = app.getArgument('notification-category');
console.log("##### category: ", category);
app.askToRegisterDailyUpdate(
'what_did_i_missed',
[{ name: "some name", textValue: "some text" }]
);
}
// Confirm outcome of opt-in for daily updates.
function finishUpdateSetup(app) {
console.log("====>> finish triggered")
if (app.isUpdateRegistered()) {
app.tell("Ok, I'll start giving you notification that time.");
} else {
app.tell("something went wrong when i was scheduling up notification");
}
}
// # NOTE
// must have to enable notification 2 places,
// - first in google action dashboard(overview>Action discovery and updates>{intent-name}>Enable User updates and notifications>set title of notification)
// - second in google cloud console(Firebase Cloud Messaging API),
// otherwise i will just keep saying '{your app name} is not responding'
function whatMissed(app) {
const status = app.getArgument("boolean");
if (status === 'yes') {
app.tell("Ok, good job. keep it up!");
} else {
app.ask("would you like me to remind you again?");
}
}
function whatMissed_yes(app) {
app.askToRegisterDailyUpdate(
'what_did_i_missed',
[{ name: "some name", textValue: "some text" }]
);
}
"In this first iteration updates are system notifications on the user's Assistant-enabled phones, but we plan to expand to new surfaces."
https://developers.google.com/actions/assistant/updates/overview
Support person is also saying it is only supported in mobile device, and not in other surfaces like google home and mini.
I am sending push notifications with One Signal to all users from the backend that uses Laravel like this:
OneSignal::sendNotificationToAll($notification->message);
I have set it up on the frontend side like this:
angular.module('coop.services')
.service('PushService', function(
AppSettings,
$rootScope,
$q
) {
var service = {
init: function() {
if (!window.plugins || !window.plugins.OneSignal) {
return;
}
window.plugins.OneSignal
.startInit( AppSettings.oneSignalAppId)
.endInit();
},
receivePush: function(data) {
$rootScope.$broadcast('push:received', data);
},
getDeviceId: function() {
var deferred = $q.defer();
if (window.plugins) {
window.plugins.OneSignal.getIds(function(ids) {
deferred.resolve(ids.userId);
});
}
else {
deferred.reject();
}
return deferred.promise;
}
};
return service;
});
I have tested both from the backend and from the One signal dashboard and when I am sending notification I get two notifications for each I send. One with alarm icon and one without any, what I am doing wrong?
you might have enabled mozila and Chrome with wrong settings, had similar problem I couldn't disactivate the browser though, I just made a new onesignal app and solved.