I'm trying to make cloud messaging server, which sends notifications to chrome (PC and mobile).
I found https://developers.google.com/web/fundamentals/getting-started/codelabs/push-notifications/ and tutorial works.
In this tutorial there is a listener:
self.addEventListener('push', function(event) {
console.log('[Service Worker] Push Received.');
console.log(`[Service Worker] Push had this data: "${event.data.text()}"`);
const title = 'Push Codelap';
const options = {
body: 'Yay it works.',
icon: 'images/icon.png',
badge: 'images/badge.png'
};
event.waitUntil(self.registration.showNotification(title, options));
});
And it works - when I send 'Hello world' through https://web-push-codelab.appspot.com/ it appears... but only in console.log.
How to change the options to get ${event.data.text()} intead of Yay it works?
I tried to change body: 'Yay it works.', into body: ${event.data.text()},
but Syntax Error: Unexpected token { appears.
The best what I did yesterday is go to sleep. Fresh mind and solution is comming immediately.
const options = {
body: event.data.text(),
icon: 'images/icon.png',
badge: 'images/badge.png'
};
Related
I'm using the following code to send a notification from one device to another using FCM. Everything works fine until before return admin.messaging().sendToDevice(...). The 'Token ID: ' log displays token ID of the receiver, but when I set the variable token_id to the sendToDevice function, the notification is not called, therefore the notification is not sent. Can someone tell me what's wrong?
var firebase = require("firebase-admin");
var serviceAccount = require("./julla-tutorial.json");
console.log("enter in then Firebase Api");
const firebaseToken = [
'e0T6j1AiRjaa7IXweJniJq:APA91bHNznSHSIey08s-C-c3gchci6wepvhP1QxQyYbmZ8LySI3wnu64iW7Q23GhA6VCdc4yodZoCFOgynfAb5C8O8VE81OcSv_LL-K3ET1IKGZ_6h35n-_q5EKFtfJWlzOqZr4IvpiB',
'dNWnSqyCQbufzv1JutNEWr:APA91bFcI9FDyRxHRBEcdw4791X0e-V0k1FjXcSstUA67l94hSojMRCd6LWr2b57azNEt3z_XLwLljMX4u2mc9cZDrAVm55Mw9CHGyue-09KofWnnHNR9XWBibc4T76xOV_DWX7T2RvW',
'cq65rtuaTCKGk5lHk7UabN:APA91bFR3kAArg6lhuBq7ktNuBk7Z9MXXk3PskqhYa8CgNaEl6MX4TQ5lo35d6XhnCQ4fEkCkyZ_j08evxE9Y4oVCRTEdqsrkccCVTE8Di47lfmDR3i1NdoL3re9oLw6F_uNsnvRoQcq'
]
firebase.initializeApp({
credential: firebase.credential.cert(serviceAccount)
})
const payload = {
notification: {
title: 'Demo 2345',
body: 'dfghj',
sound: 'default',
color: 'yellow',
android_channel_id: 'default',
channel_id: 'default'
},
data: { id: 'broadcast', channelId: 'default' }
}
const options = {
priority: 'high',
timeToLive: 60 * 60 * 24, // 1 day
};
console.log('------payload---',payload);
console.log('-----TOKEN_Array----',firebaseToken);
console.log('-------options-----',options);
firebase.messaging().sendToDevice(firebaseToken, payload, options).then(function (response) {
console.log('--------response',response);
}) .catch(function (error) {
console.log('-------rejet',reject);
});
It looks like you did not change the code from this tutorial:
https://medium.com/#jullainc/firebase-push-notifications-to-mobile-devices-using-nodejs-7d514e10dd4
you will need to change the 2nd line of code:
var serviceAccount = require("./julla-tutorial.json");
to actually point to your own firebase-push-admin.json file which holds your private keys registering your backend app with the firebase cloud messaging api. you can download this file from the firebase console as mentioned in the above article.
I recommend hiding this file from your git history by adding it to .gitignore so you dont accidentally push your private keys to a public repo.
I will link you another resource in addition to above link which helped me implement firebase push notifications in a nodeJS backend app.
https://izaanjahangir.medium.com/setting-schedule-push-notification-using-node-js-and-mongodb-95f73c00fc2e
https://github.com/izaanjahangir/schedule-push-notification-nodejs
Further I will also link you another repo where I am currently working on a fully functional firebase push notification implementation. Maybe it helps to actually see some example code.
https://gitlab.com/fiehra/plants-backend
I am trying to show a notification and do something when it is clicked. The part that shows is working well, is receiving data from the server, however, the function of clicking on the notification does not work, I have done everything the documentation says, what I found on the web and here, everything points with the same functionality that I have implemented but it doesn't seem to work. I have made fictitious practices and as long as the data is not loaded from the server, the click is triggered, otherwise, with the data it does not.
Can anyone tell me what I am doing wrong? I'll really apreciate some help, I've two days with this.
self.addEventListener('push', (e) => {
let notification = e.data.json();
const title = 'My app ' + notification.title;
const options = {
body: notification.msg,
actions: [
{ action: 'yes', title: 'Aprobar' },
{ action: 'no', title: 'Rechazar' }
]
};
self.registration.showNotification(title, options);
}); //to show the notification with server info
self.addEventListener('notificationclick', function (event) {
console.log(event);
var noti = event.notification.data;
let r = event.notification.data.json();
console.log(noti); },
false); //handling the click
I've also tried with notificationclose to see if it catchs the click but it does not work either.
Important to note that it does not display any error or warning, it does simple do anything. Found the solution! See First Answer.
I found the solution! After playing around with the code and reading some others documents, it turns out that if my service on my server is a threading type, in my js has to be waiting for an answer. If someone needs it.
let notification = '';
self.addEventListener('push', (e) => {
notification = e.data.json();
const title = 'My app' + notification.title;
const options = {
body: notification.msg,
actions: [
{ action: 'yes', title: 'Aprobar' },
{ action: 'no', title: 'Rechazar' }
]
};
e.waitUntil(self.registration.showNotification(title, options)); }); //waitUntil to show the notification
self.addEventListener('notificationclick', function (event) {
console.log('[Service Worker] Notification click Received.');
event.notification.close();
let response = event.action;
event.waitUntil(
fetch(`api/authorizations/processor?uuid=${notification.uuid}&response=${response}&account=${notification.user}`,
{
method: 'GET',
mode: 'cors',
cache: 'default'
}).then((result) => {
if (!result.ok)
throw result;
return result.json();
}).then(function (data) {
console.log(data);
}).catch(function (error) {
console.log(errow);
})
); }); // waitUntil to expect a action
I want to show push notification using a service worker. In the developer tools -> Application -> Service workers I have the test text "a": "test message", I press the push and get the following error:
serviceWorker.js:48 Uncaught (in promise) TypeError: Failed to execute
'showNotification' on 'ServiceWorkerRegistration': No notification
permission has been granted for this origin.
How can I fix this? When you click on the push button, should the notification pop up?
For Push messages, you need two API's setup Notification API and Push API.
First things first, ask permission of the client for notification. Unless that is granted nothing works. So in your index.js/App.js place this snippet:-
function askForNPerm() {
Notification.requestPermission(function(result) {
console.log("User choice", result);
if (result !== "granted") {
console.log("No notification permission granted!");
} else {
configurePushSub();// Write your custom function that pushes your message
}
});
}
Once you are allowed with the permission, then call your Push function that has message to display.
It's Work. You also need to check if your browser has permission.
self.addEventListener('push', (event) => {
const options = {
body: 'This notification was generated from a push!',
icon: '',
data: {
dateOfArrival: Date.now(),
primaryKey: '2'
},
actions: [
{
action: 'explore', title: 'Explore this new world',
icon: ''
},
{
action: 'close', title: 'Close',
icon: ''
},
]
};
event.waitUntil(
self.registration.showNotification('Title', options)
)
});
I have all push notifications working fine.
But what is missing is the ability to handle silent push notifications when the app is in the background without the need for the user to tap on the notification when it appears to process the notification.
The following is the payload code from my deployed Firebase Cloud Function written in JavaScript but it doesn't work. The notification is displayed when app is in background but no delegate methods are called for the tab bar item badge to be updated.
I understand that in order to enable this I need to add the content-available flag to my payload.
I have enabled Background Fetch and Remote Notifications to my app and declared userNotificationCenter willPresent and userNotificationCenter didReceive delegate method.
const payload = {
notification: {
title: "I'm " + senderName,
body: notificationBody,
'content-available' : 1
},
data: {
SENDER_NAME: senderName,
SENDER_ID: fromId,
NOTIFICATION: 'invite'
}//end data
}//end payload
I found a solution to my question with the help of the question link as per the comments above. As this is an FCM function the the content_available should be specified in the options instead of the payload
const payload = {
notification: {
title: senderName + " sent you a message",
body: notificationBody
},
data: {
SENDER_NAME: senderName,
SENDER_ID: fromId,
NOTIFICATION: 'message'
}//end data
}//end payload
const options = {
content_available: true
}
//send message
return admin.messaging().sendToDevice(registrationTokens, payload, options).then( response => {
I've successfully built an FCM notification service worker for my web app, and it's working OK so far. I used toastr to present notifications within the web app. I'm currently having an issue with the service worker when the web site is not open. Here is my code from firebae-messaging-sw.js:
//Firebase initialized above here
messaging.setBackgroundMessageHandler(function (payload) {
const notiTitle = payload.data.title;
var body = payload.data.body;
const opts = {
icon : "/ui/img/icons/android-chrome-256x256.png",
actions : [
{
action: 'view-ticket',
title: 'View Ticket',
icon: null
}
],
body: body
//url: link
};
self.addEventListener('notificationclick', function (event) {
const clickedNotification = event.notification;
clickedNotification.close();
if(!event.action) {
return;
}
switch(event.action) {
case 'view-ticket':
var promiseChain = clients.openWindow(payload.data.link);
break;
}
event.waitUntil(promiseChain);
});
return self.registration.showNotification(notiTitle, opts);
});
It's almost working perfectly except for one issue. When I send my first test notification, payload.data.link is parsed ok. But on the next notification, payload.data.link is not updated, so the wrong link is sent. I think that maybe self.addEventListener is in the wrong place, but I'm not sure how else to put it (I obviously can't do it after the return).
Any idea where I should put the event listener code?
I fixed it! I was able to repair this by adding a variable and moving addEventListener outside of setBackgroundMessageHandler like so:
//Firebase started up above
var clickDestination; //init this variable
//add event listener before background message handler and use clickDestination
self.addEventListener('notificationclick', function (event) {
const clickedNotification = event.notification;
clickedNotification.close();
if (!event.action) {
return;
}
if(event.action === 'view-ticket') {
var promise = new Promise(function () {
return clients.openWindow(clickDestination);
});
event.waitUntil(promise);
}
});
messaging.setBackgroundMessageHandler(function (payload) {
const notiTitle = payload.data.title;
var body = payload.data.body;
clickDestination = payload.data.link; //set clickDestination based on payload
/*self.addEventListener('notificationclick', function (event) {
event.notification.close();
event.waitUntil(self.clients.openWindow(payload.data.link));
});*/
const opts = {
icon : "/ui/img/icons/android-chrome-256x256.png",
actions : [
{
action: 'view-ticket',
title: 'View Ticket',
icon: '/ui/img/icons/ticket-icon.png'
}
],
body: body
};
return self.registration.showNotification(notiTitle, opts);