Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

event.data is always null #355

Closed
kkCode opened this issue Jun 5, 2022 · 8 comments
Closed

event.data is always null #355

kkCode opened this issue Jun 5, 2022 · 8 comments

Comments

@kkCode
Copy link

kkCode commented Jun 5, 2022

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.

@kkCode
Copy link
Author

kkCode commented Jun 5, 2022

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.

@Filikec
Copy link

Filikec commented Aug 20, 2022

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.

@levelsio
Copy link

levelsio commented Oct 17, 2023

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']
)
]);

@Minishlink
Copy link
Member

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).

@Minishlink
Copy link
Member

README updated, is it more clear? 156a3b6

@levelsio
Copy link

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).

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!

@Minishlink
Copy link
Member

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)

@levelsio
Copy link

levelsio commented Oct 19, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants