I have a difficulty concerning web push notifications. The registration of my service worker, the subscription of the user (in the DB) and the sending work properly (at least, there is no apparent error).
But navigator doesn't receive anything. It means that my service worker push event isn't executed. Tried on chrome and firefox : same results.
What can I change in my code to make my application sends notifications (or just console.log) to the navigator ?
I'm working with Symfony.
I'll give you my service worker register, user subscription, save in DB, notification sender and service worker.
Thank's if you can help me.
What I have tried:
file.js
window.onload = function () {
if (!('serviceWorker' in navigator) || !('PushManager' in window)) {
console.log("Navigateur incompatible avec les notifications")
return;
} else {
registerServiceWorker().then(function () {
askPermission().then(function () {
getNotificationPermissionState().then(function () {
subscribeUserToPush().then(function (subscription) {
sendSubscriptionToBackEnd(subscription);
})
})
})
})
}
}
function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
function getSWRegistration() {
return navigator.serviceWorker.register('http://localhost/serviceWorker.js');
}
function registerServiceWorker() {
return navigator.serviceWorker.register('http://localhost/serviceWorker.js')
.then(function (registration) {
console.log(registration)
console.log('Service worker successfully registered.');
return registration;
})
.catch(function (err) {
console.error('Unable to register service worker.', err);
});
}
function askPermission() {
return new Promise(function (resolve, reject) {
const permissionResult = Notification.requestPermission(function (result) {
resolve(result);
});
if (permissionResult) {
permissionResult.then(resolve, reject);
}
})
.then(function (permissionResult) {
if (permissionResult !== 'granted') {
throw new Error('We weren\'t granted permission.');
}
});
}
function getNotificationPermissionState() {
if (navigator.permissions) {
return navigator.permissions.query({name: 'notifications'})
.then((result) => {
return result.state;
});
}
return new Promise((resolve) => {
resolve(Notification.permission);
});
}
function subscribeUserToPush() {
return getSWRegistration()
.then(function (registration) {
const subscribeOptions = {
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(
'publicKey'
)
};
return registration.pushManager.subscribe(subscribeOptions);
})
.then(function (pushSubscription) {
console.log('Received PushSubscription: ', JSON.stringify(pushSubscription));
return pushSubscription;
});
}
function sendSubscriptionToBackEnd(subscription) {
console.log(subscription)
$.ajax({
type: "POST",
url: "{{ path('cr_whiz_sub') }}",
data: {
subscription: JSON.stringify(subscription)
},
success: function (response) {
console.log(response);
}
})
}
subscription
public function testSubAction(Request $request){
self::instancierRepository(array("Subscription"));
try {
$subscription = $request->get('subscription');
$subscription = array(json_decode($subscription, true));
$endpoint = $subscription[0]['endpoint'];
$p256dh = $subscription[0]['keys']['p256dh'];
$auth = $subscription[0]['keys']['auth'];
if (!$endpoint || !$p256dh || !$auth)
return new Response("Erreur lors de l'enregistrement", 500);
$subscription_exist = $this->repositorySubscription->findOneBy(array(
'endpoint' => $endpoint,
'p256dh' => $p256dh,
'auth' => $auth
));
if ($subscription_exist === null) {
$subscription_save = new Subscription_bdd();
$subscription_save->setEndpoint($endpoint);
$subscription_save->setP256dh($p256dh);
$subscription_save->setAuth($auth);
$this->manager->persist($subscription_save);
$this->manager->flush();
}
return new Response("Enregistrement de la souscritpion réussi", 200);
} catch (\Exception $e) {
return new Response("Erreur lors de l'enregistrement de la souscription", 500);
}
}
send notification With this bundle : https://github.com/web-push-libs/web-push-php
public function testPushAjaxAction()
{
try {
self::instancierRepository(array("Subscription"));
$subscriptions = $this->repositorySubscription->findAll();
$notifications = array();
$i = 0;
foreach ($subscriptions as $subscription) {
$notifications[$i] = [
'subscription' => Subscription::create([
'endpoint' => $subscription->getEndpoint(),
'publicKey' => $subscription->getP256dh(),
'authToken' => $subscription->getAuth(),
]),
'payload' => 'hello !',
];
$i++;
}
$auth = [
'VAPID' => [
'subject' => 'mailto:test@mail.fr',
'publicKey' => 'publicKey',
'privateKey' => 'privateKey',
],
];
$web_push = new WebPush($auth);
foreach ($notifications as $notification) {
$web_push->sendNotification(
$notification['subscription'],
$notification['payload']
);
}
$web_push->flush();
} catch (\ErrorException $e) {
return new Response("Error" . $e->getMessage(), 500);
}
return new Response("Sent", 200);
}
serviceWorker.js
self.addEventListener('push', function(event) {
console.log('[Service Worker] Push Received.');
console.log(`[Service Worker] Push had this data:`);
});