web-push-php
web-push-php copied to clipboard
event.data is always null
PHP Version: 7.4.26 web-push-php Version: 7.0.0 Browser: Microsoft Edge v104.0.1271.2
php code like this :
$notification = [
'subscription' => Subscription::create([
'endpoint' => 'https://sg2p.notify.windows.com/...', // Edge,
'publicKey' => '...', // base 64 encoded, should be 88 chars
'authToken' => '...', // base 64 encoded, should be 24 chars
]),
'payload' => json_encode([
"title"=>"have news"
]),
]
Problem
The browser can receive notification, but the event.data is always null.
After repeated attempts, I found a solution, using this notification format.
$notifications = [
'subscription' => Subscription::create([
'endpoint' => 'https://sg2p.notify.windows.com/...', // Edge,
'keys' => [
'p256dh' => '...',
'auth' => '...',
]
]),
'payload' => json_encode([
"title"=>"have news"
]),
]
P256dh and auth are obtained from the result of javascript's pushManager.subscribe.
I love u, this worked for me as well.
After repeated attempts, I found a solution, using this notification format.
$notifications = ['subscription' => Subscription::create(['endpoint' => 'https://sg2p.notify.windows.com/...', // Edge,'keys' => ['p256dh' => '...','auth' => '...',]]),'payload' => json_encode(["title"=>"have news"]),]P256dh and auth are obtained from the result of javascript's pushManager.subscribe.
Documentation of Web Push PHP seems completely wrong as in the docs at https://github.com/web-push-libs/web-push-php it says:
`<?php
use Minishlink\WebPush\WebPush; use Minishlink\WebPush\Subscription;
// array of notifications $notifications = [ [ 'subscription' => Subscription::create([ 'endpoint' => 'https://updates.push.services.mozilla.com/push/abc...', // Firefox 43+, 'publicKey' => 'BPcMbnWQL5GOYX/5LKZXT6sLmHiMsJSiEvIFvfcDvX7IZ9qqtq68onpTPEYmyxSQNiH7UD/98AUcQ12kBoxz/0s=', // base 64 encoded, should be 88 chars 'authToken' => 'CxVX6QsVToEGEcjfYPqXQw==', // base 64 encoded, should be 24 chars ]), 'payload' => 'hello !', ], ];
$webPush = new WebPush();
// send multiple notifications with payload foreach ($notifications as $notification) { $webPush->queueNotification( $notification['subscription'], $notification['payload'] // optional (defaults null) ); }
/**
-
Check sent results
-
@var MessageSentReport $report */ foreach ($webPush->flush() as $report) { $endpoint = $report->getRequest()->getUri()->__toString();
if ($report->isSuccess()) { echo "[v] Message sent successfully for subscription {$endpoint}."; } else { echo "[x] Message failed to sent for subscription {$endpoint}: {$report->getReason()}"; } }
/**
- send one notification and flush directly
- @var MessageSentReport $report */ $report = $webPush->sendOneNotification( $notifications[0]['subscription'], $notifications[0]['payload'] // optional (defaults null) ); `
This will ALWAYS produce empty data though (tested in Chrome MacOS).
Only by following the posters above I made it work. It manually takes the p256dh and auth key and inserts it into a nested array under keys. I believe the docs need to be changed because it took me hours to figure this out too!
$webPushSubscriptionObject=Subscription::create([ 'endpoint' => $webPushSubscriptionFromDb['endpoint'], 'publicKey' => $config['webPush']['key']['public'], 'authToken' => $webPushSubscriptionFromDb['auth'], 'keys'=>array( 'p256dh'=>$webPushSubscriptionFromDb['keys']['p256dh'], 'auth'=>$webPushSubscriptionFromDb['keys']['auth'] ) ]);
Yes the readme is not very clear right now, because of all the old standards and/or browser implementations. Note that even when sending a payload, some browser implementations might not respect/handle it and you should handle the case where payload is undefined on the client-side.
The PushSubscription object on the client side can currently be one of the following objects that are here. I believe most of the current browsers send the first type (with p256dh and auth) but it might also not be the case, and some users will certainly be on older/exotic browsers.
Storing the whole client-side PushSubscription object with toJSON() (see example) is the way to go. You might also store the endpoint alongside for a unique identifier.
And then you simply decode that JSON and create a subscription from it (example). It should be transparent, as browsers might change the PushSubscription object in the future (and updating this lib should be the only change necessary to handle these new cases).
README updated, is it more clear? https://github.com/web-push-libs/web-push-php/commit/156a3b65ad5d2193708833313ab2b78d0b548248
Storing the whole client-side
PushSubscriptionobject with toJSON() (see example) is the way to go. You might also store the endpoint alongside for a unique identifier. And then you simply decode that JSON and create a subscription from it (example). It should be transparent, as browsers might change thePushSubscriptionobject in the future (and updating this lib should be the only change necessary to handle these new cases).
I do that, but that does not work. Here's the saved JS subscription array from a Chrome client (with redacted keys):
{"endpoint":"https://fcm.googleapis.com/fcm/send/REDACTED","expirationTime":null,"keys":{"p256dh":"REDACTED","auth":"REDACTED"}}
Just submitting that as a subscription object into Web Push PHP fails to send data to a Chrome client. Data will always be null.
Instead we have to do modify the subscription JS array from client and add publicKey and authToken in there again, like this:
$webPushSubscriptionObject=Subscription::create([ 'endpoint' => $webPushSubscriptionFromDb['endpoint'], 'publicKey' => $config['webPush']['key']['public'], 'authToken' => $webPushSubscriptionFromDb['auth'], 'keys'=>array( 'p256dh'=>$webPushSubscriptionFromDb['keys']['p256dh'], 'auth'=>$webPushSubscriptionFromDb['keys']['auth'] ) ]);
Thanks!
That's weird, this is exactly what's being done in the example and it works flawlessly with a payload. Do you decode with json_decode($subscription, true)? (in order to have an associative array)
Yep I did, and it works because push events show up in client but event data is null in Chrome. See the other people with same problem.
On Wed, Oct 18, 2023, at 22:41, Louis Lagrange wrote:
That's weird, this is exactly what's being done in the example https://github.com/Minishlink/web-push-php-example/blob/master/src/send_push_notification.php#L9 and it works flawlessly with a payload. Do you decode with
json_decode($subscription, true)? (in order to have an associative array)— Reply to this email directly, view it on GitHub https://github.com/web-push-libs/web-push-php/issues/355#issuecomment-1769364452, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABWR2AD5U3K7Q3CLDN3PGYLYABEHLAVCNFSM5X4W73YKU5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCNZWHEZTMNBUGUZA. You are receiving this because you commented.Message ID: @.***>