Ich bin am Verzeifeln.
Ich muss unbedingt Destop Benachrichtigungen für meine PWA haben. Es wird ein provat chat und immer wenn jemand was schreibt sollen die anderen die meldung bekommen "Neue Nachricht von ..". Bei Handys soll die dann auch auf dem Sperrbildschirm angezeigt werden. Die Benachrichtigungen müssen auch escheinen wenn die App geschlossen ist, wie bei Discord.
Den Client Site code habe ich easy hinbekommen
notificationHelper.registerServiceWorker('/sw.js');
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;
}
var notificationHelper = {
isSupported() {
if (!window.Notification) {
return false;
}
if (!('serviceWorker' in navigator)) return false;
return 'PushManager' in window;
},
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;
},
createNotificationSubscription(pushServerPublicKey) {
return navigator.serviceWorker.ready.then(function(serviceWorker) {
return serviceWorker.pushManager
.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(pushServerPublicKey)
})
.then(function(pushSubscription) {
var subJSObject = JSON.parse(JSON.stringify(pushSubscription));
var subscription = {
'endpoint': subJSObject.endpoint,
'authToken': subJSObject.keys.auth,
'publicKey': subJSObject.keys.p256dh,
'contentEncoding': 'aesgcm'
}
return subscription;
});
});
},
registerServiceWorker(file) {
if (!navigator.serviceWorker) return;
navigator.serviceWorker.register(file);
}
}
function request_permission() {
Notification.requestPermission(function (status) {
if (status === 'granted') {
notificationHelper.createNotificationSubscription("<?php echo htmlspecialchars($key_public); ?>").then(function (subscription) {
console.log(subscription);
fetch('/push', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: 'data=' + encodeURIComponent(JSON.stringify(subscription)),
});
});
} else {
console.log(status);
setTimeout(request_permission, 5000);
}
});
}
request_permission();
Alles anzeigen
Wenn Jemand die Website öffnet und Benachrichtigungen zulässt bekomme ich die Push Daten auf dem Server. Diese werden dann in einer Datenbank gespeichert, oder wenn bereits vorhandne ersetzt. So verhindere ich, dass ein und dasselbe gerät die benachrichtigung doppelt bekommt. wenn jemamnd aber meherere geräte hat bekommen trotzdem alle die benachrichtigung. Das funktioniert auch alles. In der Dtanebank hab ich dann JSON einträge die wie die folgenden Aussehen:
[{"endpoint":"https:\/\/wns2-am3p.notify.windows.com\/w\/?token=BQYAAADxhCaa2w1NkpcJ3ITbt7Akq0FMaUvOr6eY9IcTJfH0Uyh5bMAqoc%2fiw4W3ePDlIMroJjukFqCWIGQ5HTTGysqK31mZUBLUnWAbEa1CUO0NatmYIXqmBcICR8QdBJBBHkGYOi4PR3rAKUob9J6fNvpdYBmPQI03OGk9mU9fyDNTOeghaa8LFTd2wM5jlgGfUFkfSf5iTuz9%2fBfk%2fQuT7ChHfBajQKmKz91j2MQpjvGfdEBFmoDEKq2qfB%2fwmFvkkAswGQiFwI%2bMnGqB%2bpXHVGRxGFjZw%2bXestloVF%2f9j15pk0AKwqqxl%2fFtiV%2f2CVLbnsc%3d","authToken":"MMXpFVr9sGYXvquvAlZuyA","publicKey":"BPlyW1ROqnYdys3ono36BhsvqdFVBdfeC6jtBNrPMRxnYTPPL8QsDYQTmYfwGFE7aSQoAm75E6Nc3UIcfHYib2Q"},{"endpoint":"https:\/\/wns2-am3p.notify.windows.com\/w\/?token=BQYAAADxhCaa2w1NkpcJ3ITbt7Akq0FMaUvOr6eY9IcTJfH0Uyh5bMAqoc%2fiw4W3ePDlIMroJjukFqCWIGQ5HTTGysqK31mZUBLUnWAbEa1CUO0NatmYIXqmBcICR8QdBJBBHkGYOi4PR3rAKUob9J6fNvpdYBmPQI03OGk9mU9fyDNTOeghaa8LFTd2wM5jlgGfUFkfSf5iTuz9%2fBfk%2fQuT7ChHfBajQKmKz91j2MQpjvGfdEBFmoDEKq2qfB%2fwmFvkkAswGQiFwI%2bMnGqB%2bpXHVGRxGFjZw%2bXestloVF%2f9j15pk0AKwqqxl%2fFtiV%2f2CVLbnsc%3d","authToken":"MMXpFVr9sGYXvquvAlZuyA","publicKey":"BPlyW1ROqnYdys3ono36BhsvqdFVBdfeC6jtBNrPMRxnYTPPL8QsDYQTmYfwGFE7aSQoAm75E6Nc3UIcfHYib2Q"}]
Das sieht mir auch richtig aus, oder?
Wenn ich jetzt Benachrichtigungen senden will mache ich das wie folgt. Ich bin ja immer etwas abgeneigt gegenüber fremden bibliotecken und modulen aber weil ich keine anderen tutorials gefunden hab, hab ich mich für die php bibliteck web-push entschieden. Mit ein bischen rumprobieren, weil meine web-push version offenbar neuer war als die im tutorial (eine methode hatte einen andernen namen) sah der code am ende funktionsfähig aus.
$key_public = "BOwepYjLEZEMN0YPlh1NJOr4keeVYEta6mSq4GHX22Uiml9_768M-sHMJpljNRbui7r7C5APr2yjmiwTs3LlcLg";
$key_private = "O7i8vFrZ7HUaNYAl2Wv7Ds8_Gu2pUg-bD8Ddftuy5lc";
$auth = [
'VAPID' => [
'subject' => 'https://lanparty2023.de',
'publicKey' => $key_public,
'privateKey' => $key_private
]
];
$payload = [
"title" => "Neue Nachricht von ".$_POST["name"],
"body" => $_POST["text"] ?? "",
"badge" => "/image.jpg",
"icon" => "/favicon.ico",
"image" => "https://lanparty2023.de/image.jpg",
"tag" => "Programmierer Lanparty",
"actions" => [
[
"action" => "open",
"title" => "Nachricht lesen"
],
[
"action" => "open",
"title" => "Antworten"
]
],
"data" => [
"open" => "/invite/",
"default" => "/invite/"
],
"vibrate" => [300, 100, 400]
];
$webPush = new \Minishlink\WebPush\WebPush($auth);
$has = array();
foreach($pushTokens as $data){
if(isset($has[json_encode($data)])) continue;
$has[json_encode($data)] = true;
$subscription = \Minishlink\WebPush\Subscription::create($data);
$result = $webPush->sendNotification(
$subscription,
$payload
);
echo $result;
exit();
Alles anzeigen
Und das Funktionier einfach nicht!!!!! Egal was ich tue. Seid stunden bin ich am rumprobieren. Es heißt immer Response 401 - Unatorizied
ich habe auch schon chatgpt noch einer manullen version über curl gefragt aber die ist so dumm und unssing, dass kein Broweser die Anfrage überhaupt erst akzeptiert.
Ist mein Valid Keys vielleicht falsch? oder woran kann es noch liegen? ich habe es mit 4 verschiedenen browsern, 2 computern, 1 handy und browserling probiert aber überall erhalte ich 401.
Ich wäre meinem Retter unendlich dank bar