I'm try to implement Push Notifications in Chrome with ServiceWorkers and GCM.
The notifications working fine, but the push function the event is null (self.addEventListener('push', function(event)
).
The next is my code and working fine, received the notifications, but don't receive the data.
To register:
<script>
document.addEventListener('DOMContentLoaded', function () {
/*navigator.serviceWorker.getRegistration().then(function(r) {
r.unregister();
});*/
// document.querySelector("#enablepush").addEventListener('click', function (e) {
//if(Notification.permission !== 'granted') {
Notification.requestPermission().then(function (permission) {
if (permission === 'granted' && 'serviceWorker' in navigator) {
navigator.serviceWorker.register('myworker.js').then(initialiseState);
} else {
console.log('service worker not present');
}
});
//}
// });
//get subscription token if already subscribed
if (Notification.permission === 'granted') {
navigator.serviceWorker.ready.then(function (registration) {
registration.pushManager.getSubscription().then(function (subscription) {
getToken(subscription);
});
});
}
});
function SalirPush()
{
console.log("Si registro ha sido cancelado");
navigator.serviceWorker.getRegistration().then(function (r) {
r.unregister();
});
navigator.serviceWorker.ready.then(function (reg) {
reg.pushManager.getSubscription().then(function (subscription) {
subscription.unsubscribe().then(function (successful) {
// You've successfully unsubscribed
}).catch(function (e) {
// Unsubscription failed
})
})
});
}
function initialiseState() {
//check if notification is supported or not
if (!('showNotification' in ServiceWorkerRegistration.prototype)) {
console.warn('Notificaiton are not supported');
return;
}
//check if user has blocked push notification
if (Notification.permission === 'denied') {
console.warn('User has blocked the notification');
}
//check if push messaging is supported or not
if (!('PushManager' in window)) {
console.warn('Push messaging is not supported');
return;
}
//subscribe to GCM
navigator.serviceWorker.ready.then(function (serviceWorkerRegistration) {
//call subscribe method on serviceWorkerRegistration object
serviceWorkerRegistration.pushManager.subscribe({userVisibleOnly: true})
.then(function (subscription) {
getToken(subscription);
var met = JSON.stringify(subscription);
console.log("Mensaje", met);
}).catch(function (err) {
console.error('Error occured while subscribe(): ', err);
});
});
}
function getToken(subscription) {
console.log(subscription);
var token = subscription.endpoint.substring(40, subscription.endpoint.length);
//document.querySelector("#token").innerHTML = token;
try
{
$("#apikey").val(token);
}catch (e)
{
}
}
</script>
Next my workers.js is;
self.addEventListener('push', function(event) {
var url = "/push/json-data.php?param=(This is the event data info)";
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);
}
})
);
});
Next to send the Push Notifications, I use this PHP:
<?php
$estado=$_GET["estado"];
$idtoken=$_GET["id"];
$op=$_GET["op"];
if ($op != "")
{
sendFCM("My App","Hi to all", $idtoken,$estado);
}
function sendFCM($titulo,$mess,$id,$estado) {
echo "Recibi: $mess , $id, $estado";
$data = array('status'=> $estado,'mensaje'=>'"'.$mess.'"','titulo'=>'"'.$titulo.'"');
$url = 'https://fcm.googleapis.com/fcm/send';
$fields = array (
'to' => $id,
'notification' => array (
"body" => $mess,
"title" => $titulo,
"icon" => "myicon",
"color"=> "#0000ff",
"sound" => "default"
),
'data' => $data,
'payload' => $data
);
$fields = json_encode ( $fields );
$headers = array (
'Authorization: key=' . "MyGoogleKey",
'Content-Type: application/json'
);
$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_URL, $url );
curl_setopt ( $ch, CURLOPT_POST, true );
curl_setopt ( $ch, CURLOPT_HTTPHEADER, $headers );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $fields );
$result = curl_exec ( $ch );
curl_close ( $ch );
echo ($result);
}
?>
Thanks for your help.