I have a difficulty concerning web push notifications. Indeed, 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. I'm working with Symfony.
Thank's if you can help me. Bye.
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(),// base 64 encoded, should be 88 chars
'authToken' => $subscription->getAuth(), // base 64 encoded, should be 24 chars
]),
'payload' => 'hello !',
];
$i++;
}
$auth = [
'VAPID' => [
'subject' => 'mailto:test@mail.fr', // can be a mailto: or your website address
'publicKey' => 'publicKey', // (recommended) uncompressed public key P-256 encoded in Base64-URL
'privateKey' => 'privateKey', // (recommended) in fact the secret multiplier of the private key encoded in Base64-URL
],
];
$web_push = new WebPush($auth);
foreach ($notifications as $notification) {
$web_push->sendNotification(
$notification['subscription'],
$notification['payload'] // optional (defaults null)
);
}
$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:`); });