Gcm push notification message is sending properly to endpoints when browser is open :Notification messages which are in json file.
serviceWorker.js
'use strict';
self.addEventListener('install', function(event) {
self.skipWaiting();
console.log('Installed', event);
});
self.addEventListener('activate', function(event) {
console.log('Activated', event);
});
self.addEventListener('push', function(event) {
console.log('Started', self);
self.addEventListener('install', function(event) {
self.skipWaiting();
});
self.addEventListener('activate', function(event) {
console.log('Activated', event);
});
self.addEventListener('push', function(event) {
var url = "http://localhost/pntest/gmpush1.json?param="+Math.random();
event.waitUntil(
fetch(url).then(function(response) {
if (response.status !== 200) {
console.log('Problem. Status Code: ' + response.status);
throw new Error();
}
// Examine the text in the response
return response.json().then(function(data) {
if (data.error || !data.notification) {
console.error('The API returned an error.', data.error);
throw new Error();
}
var promises = [];
for(var i=0; data.notification && i < data.notification.length; i++) {
promises.push(self.registration.showNotification(data.notification[i].title, {
body: data.notification[i].body,
'renotify': true,
icon: data.notification[i].icon
//tag: notification.tag
}));
}
return Promise.all( promises );
});
})
);
});
self.addEventListener('notificationclick', function(event) {
console.log('Notification click: tag ', event.notification.tag);
event.notification.close();
var newurl = event.notification.data.newurl;
console.log(newurl.updatedurl);
var url = newurl.updatedurl;
event.waitUntil(
clients.matchAll({
type: 'window'
})
.then(function(windowClients) {
console.log(url);
for (var i = 0; i < windowClients.length; i++) {
var client = windowClients[i];
if (client.url === url && 'focus' in client) {
return client.focus();
}
}
if (clients.openWindow) {
return clients.openWindow(url);
}
})
);
});
});
gcmpush1.json
{"notification": [{"body": "Test data", "url": "https://www.google.com/", "icon": "http://www.wired.com/wp-content/uploads/2015/09/google-logo-1200x630.jpg", "title": "Test Notification"}]}
When browser is open, It's showing original message
Test Notification
If client browser is in offline(not opened) while my curl trigger. When reopening the client browser i suppose to get original message but what i'm getting is
site has been updated in the background
In my curl call, I have used 'time_to_live' = 2419200.
Whenever notification failed to load data to show on chrome notification window and 'PUSH' event generate successfully. It will show "site has been updated in the background". (Nothing to do with notification delivery from Curl. it may be fine)
Couple of observations from you service worker code:
1). You are using localhost path to fetch data, will create problem to load notification data while localhost will be offline.
var url = "http://localhost/pntest/gmpush1.json?param="+Math.random();
2). You are using two 'PUSH' event code in your SW. can wrap work in one function.
self.addEventListener('push', function(event) {...
You can refer below URL for creating simple service worker to get dynamic data for push notification.
https://developers.google.com/web/updates/2015/03/push-notifications-on-the-open-web?hl=en
Related
I would like to show GCM service worker message only when there is no open chrome tab in my website or the tab is open and not selected (active).
Here is my code.
Error: chrome is not defined(…).
manifest.json
{
"name": "Webplus Express",
"short_name": "Webplus Express",
"icons": [{
"src": "https://raw.githubusercontent.com/deanhume/typography/gh-pages/icons/typography.png",
"sizes": "192x192",
"type": "image/png"
}],
"start_url": "/index.html",
"display": "standalone",
"gcm_sender_id": "298340340811",
"gcm_user_visible_only": true,
"background": {
"scripts": ["service-worker.js"]
},
"permissions": [
"gcm","tabs","activeTab"
]
}
service-worker.js
// The service worker running in background to receive the incoming
// push notifications and user clicks
self.addEventListener('push', function(event) {
// Since there is no payload data with the first version
// of push messages, we'll grab some data from
// an API and use it to populate a notification
var s_id=0;
self.registration.pushManager.getSubscription().then(function(subscription) {
if(subscription!=null){
s_id= subscription.endpoint.split("/").slice(-1);
var mURL="https://www.webplusexpress.com";
var ok=true;
chrome.tabs.getAllInWindow(undefined, function(tabs) {
for (var i = 0;i<tabs.length; i++) {
if (tabs[i].url && (tabs[i].url.indexOf(mURL)!=-1)) {
//chrome.tabs.update(tab.id, {selected: true});
if(tabs[i].highlighted){
ok=false;
}
return;
}
}
});
if (ok){
event.waitUntil(fetch('https://www.wpe.com/pushnotifyapi?s_id='+s_id).then(function(response) {
if (response.status !== 200) {
// Either show a message to the user explaining the error
// or enter a generic message and handle the
// onnotificationclick event to direct the user to a web page
console.log('Looks like there was a problem. Status Code: ' + response.status);
throw new Error();
}
// Examine the text in the response
return response.json().then(function(data) {
if (data.error || !data.notification) {
console.error('The API returned an error.', data.error);
throw new Error();
}
var title = data.notification.title;
var message = data.notification.message;
var icon = data.notification.icon;
console.log('icon received'+icon);
var notificationTag = data.notification.tag;
return self.registration.showNotification(title, {
body: message,
icon: icon,
tag: notificationTag
});
});
}).catch(function(err) {
console.error('Unable to retrieve data', err);
var title = 'An error occurred';
var message = 'We were unable to get the information for this push message';
var icon = 'https://www.webplusexpress.com/images/3web+carre.png';
var notificationTag = 'notification-error';
return self.registration.showNotification(title, {
body: message,
icon: icon,
tag: notificationTag
});
})
);
}
}
});
});
self.addEventListener('notificationclick', function(event) {
console.log('On notification click: ', event.notification.tag);
// Android doesn't close the notification when you click on it
// See: http://crbug.com/463146
event.notification.close();
// This looks to see if the current is already open and
// focuses if it is
event.waitUntil(
clients.matchAll({
type: "window"
})
.then(function(clientList) {
for (var i = 0; i < clientList.length; i++) {
var client = clientList[i];
if (client.url == '/' && 'focus' in client)
return client.focus();
}
if (clients.openWindow) {
return clients.openWindow('/');
}
})
);
});
Referring to Implementing Push Messaging for Chrome might help. It shows each step you need to complete in order to support push messaging in your web app wherein checking if service workers are supported is done before registering the service-worker.js file.
In addition to that, using Page Visibility API to detect when a webpage is visible or in focus might also help. When the user minimizes the webpage or moves to another tab, the API sends a visibilitychange event regarding the visibility of the page as done in SO post - Is there a way to detect if a browser window is not currently active?
I have created Chrome extension and use pusher to receive some data from server.
When I test it show multiple duplicate data because it follow tabs that I opened.
anyone understand me.Help me please.Thank you in advance.
Content.js
Pusher.Util.getLocalStorage = function()
{
return undefined;
}
Pusher.ScriptRequest.prototype.send = function(receiver) {
var xhr = new XMLHttpRequest();
xhr.open("GET", this.src, true);
xhr.send();
}
document.addEventListener('DOMContentLoaded', function () {
if (Notification.permission !== "granted")
Notification.requestPermission();
});
var pusher = new Pusher('xxxxxxxxxxxxxxxxxxxxx');
var notificationsChannel = pusher.subscribe('notifications');
notificationsChannel.bind('new_notification', function(notification){
// assign the notification's message to a <div></div>
var message = notification.message;
if (!Notification) {
alert('Desktop notifications not available in your browser. Try Chromium.');
return;
}
if (Notification.permission !== "granted")
Notification.requestPermission();
else {
console.log(message);
var notification = new Notification('แจ้งเตือน', {
icon: 'img/LOGO.png',
body: message,
});
notification.onclick = function () {
location.reload();
};
}
});
duplicate notification
I used Service Worker to send Push Notifications to chrome browser.
I used below code to receive notification from server
var url = "path/to/your/json/file/json-data.php?param="+Math.random();
self.addEventListener('push', function(event) {
event.waitUntil(
fetch(url).then(function(response) {
if (response.status !== 200) {
// Either show a message to the user explaining the error
// or enter a generic message and handle the
// onnotificationclick event to direct the user to a web page
console.log('Looks like there was a problem. Status Code: ' + response.status);
throw new Error();
}
// Examine the text in the response
return response.json().then(function(data) {
if (data.error || !data.notification) {
console.log('The API returned an error.', data.error);
throw new Error();
}
var title = data.notification.title;
var message = data.notification.message;
var icon = data.notification.icon;
return self.registration.showNotification(title, {
body: message,
icon: icon,
data: {
url: data.notification.url
}
});
});
}).catch(function(err) {
console.log('Unable to retrieve data', err);
var title = 'An error occurred';
var message = 'We were unable to get the information for this push message';
var icon = 'img/design19.jpg';
var notificationTag = 'notification-error';
return self.registration.showNotification(title, {
body: message,
icon: icon,
tag: notificationTag
});
})
);
});
// The user has clicked on the notification ...
self.addEventListener('notificationclick', function(event) {
console.log(event.notification.data.url);
// Android doesn't close the notification when you click on it
// See: http://crbug.com/463146
event.notification.close();
// This looks to see if the current is already open and
// focuses if it is
event.waitUntil(
clients.matchAll({
type: "window"
})
.then(function(clientList) {
for (var i = 0; i < clientList.length; i++) {
var client = clientList[i];
if (client.url == '/' && 'focus' in client)
return client.focus();
}
if (clients.openWindow) {
return clients.openWindow(event.notification.data.url);
}
})
);
});
Notification is displaying but it is closing after a few seconds. I don't need to close the notification. The user explicitly closes the notification. Tell me the code to stop closing the notification. Once the notification is displayed it is not closing forever. User explicitly close the notification
return self.registration.showNotification(title, {
body: message,
icon: icon,
tag: notificationTag
});
You can add requireInteraction: true to the notification porperties dictionary. This will make it stay on screen. Note that this is not guaranteed to work in all platforms but today at least it works ok in chrome desktop.
I have a common serviceworker escenario, where I want catch a notification click and focus the tab where the notification has come from. However, clients variable is always empty, its lenght is 0
console.log("sw startup");
self.addEventListener('install', function (event) {
console.log("SW installed");
});
self.addEventListener('activate', function (event) {
console.log("SW activated");
});
self.addEventListener("notificationclick", function (e) {
// Android doesn't automatically close notifications on click
console.log(e);
e.notification.close();
// Focus tab if open
e.waitUntil(clients.matchAll({
type: 'window'
}).then(function (clientList) {
console.log("clients:" + clientList.length);
for (var i = 0; i < clientList.length; ++i) {
var client = clientList[i];
if (client.url === '/' && 'focus' in client) {
return client.focus();
}
}
if (clients.openWindow) {
return clients.openWindow('/');
}
}));
});
And the registration is this one:
this.doNotify = function (notification) {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('sw.js').then(function (reg) {
requestCreateNotification(notification, reg);
}, function (err) {
console.log('sw reg error:' + err);
});
}
...
}
chrome://serviceworker-internals/ output shows that registration and installation are fine. However, when a notification is pushed, clientList is empty. I have tried removing the filter type:'window' but the result is still the same. As clients are empty, a new window is always opened. What am I doing wrong?
The suspicion in your own comment is correct. A page is controlled by a service worker on navigation to an origin that the service worker is registered for. So the original page load that actually initializes the service worker is not itself controlled. That's why the worker only finds your tab once you visit with a new tab or do a refresh.
However (as Jeff Posnick points out in the comments) you can get uncontrolled pages as follows: ServiceWorkerClients.matchAll({includeUncontrolled: true, type: 'window'}).
Try making the service worker immediately claim the page.
E.g.:
self.addEventListener('install', event => event.waitUntil(self.skipWaiting()));
self.addEventListener('activate', event => event.waitUntil(self.clients.claim()));
For a more complex example, see https://serviceworke.rs/immediate-claim.html.
I'm tring to use the web notifications API like in this example:
http://www.inserthtml.com/2013/10/notification-api/?utm_source=html5weekly&utm_medium=email
When i'm in this website, everything is working great, in the console i'm writing "Notification.permission" and gets "granted".
But if i'm trying to do the same in my website, i'm getting error about the Notification object and when i'm trying to print "Notification.permission" i've noticed that the Notification object doesn't have this property and other properties like "requestPermition".
This happening in all the browsers and they all updated to the last version.
i've tried to open console in other websites, like cnn.com for example, and inspect the Notifications object, and also there are missing properties.
Any idea why?? and how its working the website above??
thanks.
this is my code:
window.addEventListener('load', function(){
var button = document.getElementById( "notifications" );
function theNotification() {
var n = new Notification("Hi!", {
});
}
// When the button is clicked
button.addEventListener('click', function () {
// If they are not denied (i.e. default)
if (Notification && Notification.permission !== "denied") {
// Request permission
Notification.requestPermission( function( status ){
// Change based on user's decision
if (Notification.permission !== status)
Notification.permission = status;
});
}
});
$(button).click();
var socket = io.connect('http://localhost:3000', {query : "user=343"});
socket.on('notification', function (data) {
console.log( data );
if (Notification && Notification.permission === "granted") {
theNotification();
} else {
alert(data);
}
});
});