Я хотел бы реализовать push-уведомления на веб-сайте, но я не могу вызвать push-событие с помощью PHP и веб-push-библиотеки , даже если кажется, что сообщение успешно отправлено.
Я пытался вызвать событие из консоли (chrome), и оно работает.
Работник службы:
self.addEventListener('install', async event => {
// works fine
console.log('install event')
});
self.addEventListener("push", function(event) {
// console logs work only when I press push button in the console
console.log( 'push event' );
console.log( event );
var data = event.data.json();
event.waitUntil(self.registration.showNotification(data.title, {
body: data.body,
icon: data.icon,
tag: data.tag
}));
});
Конечная точка Php (push.php):
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Minishlink\WebPush\WebPush;
use Minishlink\WebPush\Subscription;
$auth = [
'VAPID' => [
'subject' => 'mailto:me@website.com', // can be a mailto: or your website address
'publicKey' => 'BL9qxdhqL_CM1ROLo6AUfeBvEyUuD7EHT3lAz8ksBZSYPsdE6q__uU2FoX9lr5FtmWtlHs-HRMHen3Ki8WWSVA4', // (recommended) uncompressed public key P-256 encoded in Base64-URL
'privateKey' => '7ldG3QYcY9KStB07ytTnd0CRCVSxbHfHYLyWEmgBKo0', // (recommended) in fact the secret multiplier of the private key encoded in Base64-URL
],
];
$subscription = Subscription::create([
// I'm using post just for test, in production I will fetch endpoints from database
'endpoint' => $_POST['endpoint'], // I get the value from subscription object
"keys" => [
'p256dh' => 'BL9qxdhqL_CM1ROLo6AUfeBvEyUuD7EHT3lAz8ksBZSYPsdE6q__uU2FoX9lr5FtmWtlHs-HRMHen3Ki8WWSVA4',
'auth' => '7ldG3QYcY9KStB07ytTnd0CRCVSxbHfHYLyWEmgBKo0'
],
'contentEncoding' => 'aesgcm',
]);
$webPush = new WebPush($auth);
$sent = $webPush->sendNotification($subscription, 'Hi');
foreach ($webPush->flush() as $report) {
$endpoint = $report->getRequest()->getUri()->__toString();
if ($report->isSuccess()) {
// I get this in the response
echo "[v] Message sent successfully for subscription {$endpoint}.";
} else {
echo "[x] Message failed to sent for subscription {$endpoint}: {$report->getReason()}";
}
}
Мой javascript:
async function registerSw () {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./sw.js').then(function(registration) {
subscribeToPush();
}).catch(error => console.log(error));
} else {
alert('Service workers not supported');
}
}
async function subscribeToPush () {
navigator.serviceWorker.ready.then(function(registration) {
registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey:
urlB64ToUint8Array('BL9qxdhqL_CM1ROLo6AUfeBvEyUuD7EHT3lAz8ksBZSYPsdE6q__uU2FoX9lr5FtmWtlHs-HRMHen3Ki8WWSVA4')
})
.then(function(subscription) {
// The subscription was successful
ajax(subscription);
})
.catch(function(e) {
console.log( e );
});
});
}
function urlB64ToUint8Array(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 ajax (subscription) {
console.log( 'in ajax' );
console.log( subscription );
$.ajax({
url: 'push.php',
type: 'POST',
data: {
'endpoint': subscription.endpoint,
},
success: function( response ) {
// response = JSON.parse( response );
console.log(typeof response);
console.log(response);
// I get message was sent successfuly here
},
error: function (xhr, status, error) {
console.log( xhr.responseText );
}
});
}
Сервисный работник успешно зарегистрирован, я могу запросить разрешение пользователя и отправить значения из объекта подписки обратно в бэкэнд, все идет хорошо с веб-push, но событие все еще продолжаетсяне вызывается.
Любая помощь будет оценена, спасибо.