У меня возникли проблемы с push-уведомлениями в Интернете. Действительно, регистрация моего сервисного работника, подписка пользователя (в БД) и отправка работают правильно (по крайней мере, явной ошибки нет).
Но навигатор ничего не получает.
Я работаю с Symfony.
Спасибо, если вы можете мне помочь. До свидания.
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);
}
})
}
подписка
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);
}
}
отправить уведомление
С этим комплектом: 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:[email protected]', // 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:`); });
Задача ещё не решена.
Других решений пока нет …