Skip to content

Commit 410b1fa

Browse files
authored
chore: restructure readme (#393)
Add deprecation of FCM Fix library does not send notification. It sends push message.
1 parent 7df8892 commit 410b1fa

File tree

1 file changed

+108
-36
lines changed

1 file changed

+108
-36
lines changed

README.md

+108-36
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
# WebPush
2+
23
> Web Push library for PHP
34
45
[![Build Status](https://github.com/web-push-libs/web-push-php/actions/workflows/tests.yml/badge.svg)](https://github.com/web-push-libs/web-push-php/actions/workflows/tests.yml)
56

6-
WebPush can be used to send notifications to endpoints which server delivers Web Push notifications as described in
7-
the [Web Push protocol](https://datatracker.ietf.org/doc/html/rfc8030).
8-
As it is standardized, you don't have to worry about what server type it relies on.
7+
WebPush can be used to send push messages to endpoints as described in the [Web Push protocol](https://datatracker.ietf.org/doc/html/rfc8030).
8+
9+
This push message is then received by the browser, which can then create a notification using the [service worker](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API) and the [Notifications API](https://developer.mozilla.org/en-US/docs/Web/API/Notifications_API).
910

1011
## Requirements
1112

1213
PHP 8.1+ and the following extensions:
13-
* bcmath and/or gmp (optional but better for performance)
14-
* mbstring
15-
* curl
16-
* openssl (with elliptic curve support)
14+
15+
- bcmath and/or gmp (optional but better for performance)
16+
- mbstring
17+
- curl
18+
- openssl (with elliptic curve support)
1719

1820
There is no support and maintenance for older PHP versions, however you are free to use the following compatible versions:
21+
1922
- PHP 5.6 or HHVM: `v1.x`
2023
- PHP 7.0: `v2.x`
2124
- PHP 7.1: `v3.x-v5.x`
@@ -26,11 +29,21 @@ There is no support and maintenance for older PHP versions, however you are free
2629
This README is only compatible with the latest version. Each version of the library has a git tag where the corresponding README can be read.
2730

2831
## Installation
32+
2933
Use [composer](https://getcomposer.org/) to download and install the library and its dependencies.
3034

31-
`composer require minishlink/web-push`
35+
```bash
36+
composer require minishlink/web-push
37+
```
3238

3339
## Usage
40+
41+
### Example
42+
43+
A complete example with html+JS frontend and php backend using `web-push-php` can be found here: [Minishlink/web-push-php-example](https://github.com/Minishlink/web-push-php-example)
44+
45+
### Send Push Message
46+
3447
```php
3548
<?php
3649

@@ -111,21 +124,16 @@ foreach ($webPush->flush() as $report) {
111124
*/
112125
$report = $webPush->sendOneNotification(
113126
$notifications[0]['subscription'],
114-
$notifications[0]['payload'] // optional (defaults null)
127+
$notifications[0]['payload'], // optional (defaults null)
115128
);
116129
```
117130

118-
### Full examples of Web Push implementations
119-
* An example with web-push-php: [Minishlink/web-push-php-example](https://github.com/Minishlink/web-push-php-example)
120-
* Matthew Gaunt's [Web Push Book](https://web-push-book.gauntface.com) - a must read
121-
* Mozilla's [ServiceWorker Cookbooks](https://github.com/mdn/serviceworker-cookbook/blob/master/push-payload/README.md) (don't mind the `server.js` file: it should be replaced by your PHP server code with this library)
122-
* Google's [introduction to push notifications](https://developers.google.com/web/fundamentals/getting-started/push-notifications/) (as of 03-20-2016, it doesn't mention notifications with payload)
123-
* you may want to take a look at my own implementation: [sw.js](https://github.com/Minishlink/physbook/blob/9bfcc2bbf7311a5de4628eb8f3ae56b6c3e74067/web/service-worker.js) and [app.js](https://github.com/Minishlink/physbook/blob/02a0d5d7ca0d5d2cc6d308a3a9b81244c63b3f14/app/Resources/public/js/app.js)
124-
125131
### Authentication (VAPID)
132+
126133
Browsers need to verify your identity. A standard called VAPID can authenticate you for all browsers. You'll need to create and provide a public and private key for your server. These keys must be safely stored and should not change.
127134

128135
You can specify your authentication details when instantiating WebPush. The keys can be passed directly (recommended), or you can load a PEM file or its content:
136+
129137
```php
130138
<?php
131139

@@ -148,22 +156,25 @@ $webPush->queueNotification(...);
148156
```
149157

150158
In order to generate the uncompressed public and secret key, encoded in Base64, enter the following in your Linux bash:
151-
```
159+
160+
```bash
152161
$ openssl ecparam -genkey -name prime256v1 -out private_key.pem
153162
$ openssl ec -in private_key.pem -pubout -outform DER|tail -c 65|base64|tr -d '=' |tr '/+' '_-' >> public_key.txt
154163
$ openssl ec -in private_key.pem -outform DER|tail -c +8|head -c 32|base64|tr -d '=' |tr '/+' '_-' >> private_key.txt
155164
```
156165

157166
If you can't access a Linux bash, you can print the output of the `createVapidKeys` function:
167+
158168
```php
159169
var_dump(VAPID::createVapidKeys()); // store the keys afterwards
160170
```
161171

162172
On the client-side, don't forget to subscribe with the VAPID public key as the `applicationServerKey`: (`urlBase64ToUint8Array` source [here](https://github.com/Minishlink/physbook/blob/02a0d5d7ca0d5d2cc6d308a3a9b81244c63b3f14/app/Resources/public/js/app.js#L177))
173+
163174
```js
164175
serviceWorkerRegistration.pushManager.subscribe({
165-
userVisibleOnly: true,
166-
applicationServerKey: urlBase64ToUint8Array(vapidPublicKey)
176+
userVisibleOnly: true,
177+
applicationServerKey: urlBase64ToUint8Array(vapidPublicKey)
167178
})
168179
```
169180

@@ -176,6 +187,7 @@ $webPush->setReuseVAPIDHeaders(true);
176187
```
177188

178189
### Notifications and default options
190+
179191
Each notification can have a specific Time To Live, urgency, and topic.
180192
The WebPush standard states that `urgency` is optional but some users reports that Safari throws errors when it is not specified. This might be fixed in the future.
181193
You can change the default options with `setDefaultOptions()` or in the constructor:
@@ -192,7 +204,7 @@ $defaultOptions = [
192204
'batchSize' => 200, // defaults to 1000
193205
];
194206

195-
// for every notifications
207+
// for every notification
196208
$webPush = new WebPush([], $defaultOptions);
197209
$webPush->setDefaultOptions($defaultOptions);
198210

@@ -201,25 +213,30 @@ $webPush->sendOneNotification($subscription, $payload, ['TTL' => 5000]);
201213
```
202214

203215
#### TTL
204-
Time To Live (TTL, in seconds) is how long a push message is retained by the push service (eg. Mozilla) in case the user browser
205-
is not yet accessible (eg. is not connected). You may want to use a very long time for important notifications. The default TTL is 4 weeks.
206-
However, if you send multiple nonessential notifications, set a TTL of 0: the push notification will be delivered only
207-
if the user is currently connected. For other cases, you should use a minimum of one day if your users have multiple time
216+
217+
Time To Live (TTL, in seconds) is how long a push message is retained by the push service (eg. Mozilla) in case the user browser
218+
is not yet accessible (eg. is not connected). You may want to use a very long time for important notifications. The default TTL is 4 weeks.
219+
However, if you send multiple nonessential notifications, set a TTL of 0: the push notification will be delivered only
220+
if the user is currently connected. For other cases, you should use a minimum of one day if your users have multiple time
208221
zones, and if they don't several hours will suffice.
209222

210223
#### urgency
211-
Urgency can be either "very-low", "low", "normal", or "high". If the browser vendor has implemented this feature, it will save battery life on mobile devices (cf. [protocol](https://tools.ietf.org/html/draft-ietf-webpush-protocol-08#section-5.3)).
224+
225+
Urgency can be either "very-low", "low", "normal", or "high". If the browser vendor has implemented this feature, it will save battery life on mobile devices (cf. [protocol](https://datatracker.ietf.org/doc/html/rfc8030#section-5.3)).
212226

213227
#### topic
214-
Similar to the old `collapse_key` on legacy GCM servers, this string will make the vendor show to the user only the last notification of this topic (cf. [protocol](https://tools.ietf.org/html/draft-ietf-webpush-protocol-08#section-5.4)).
228+
229+
This string will make the vendor show to the user only the last notification of this topic (cf. [protocol](https://datatracker.ietf.org/doc/html/rfc8030#section-5.4)).
215230

216231
#### batchSize
232+
217233
If you send tens of thousands notifications at a time, you may get memory overflows due to how endpoints are called in Guzzle.
218234
In order to fix this, WebPush sends notifications in batches. The default size is 1000. Depending on your server configuration (memory), you may want
219235
to decrease this number. Do this while instantiating WebPush or calling `setDefaultOptions`. Or, if you want to customize this for a specific flush, give
220236
it as a parameter : `$webPush->flush($batchSize)`.
221237

222238
### Server errors
239+
223240
You can see what the browser vendor's server sends back in case it encountered an error (push subscription expiration, wrong parameters...).
224241

225242
* `sendOneNotification()` returns a [`MessageSentReport`](https://github.com/web-push-libs/web-push-php/blob/master/src/MessageSentReport.php)
@@ -256,29 +273,34 @@ foreach ($webPush->flush() as $report) {
256273

257274
**PLEASE NOTE:** You can only iterate **once** over the `\Generator` object.
258275

259-
Firefox errors are listed in the [autopush documentation](https://autopush.readthedocs.io/en/latest/http.html#errors).
276+
Firefox errors are listed in the [autopush documentation](https://mozilla-services.github.io/autopush-rs/errors.html).
260277

261278
### Payload length, security, and performance
279+
262280
Payloads are encrypted by the library. The maximum payload length is theoretically 4078 bytes (or ASCII characters).
263-
For [compatibility reasons](https://github.com/mozilla-services/autopush/issues/748) though, your payload should be less than 3052 bytes long.
281+
For [compatibility reasons (archived)](https://github.com/mozilla-services/autopush/issues/748) though, your payload should be less than 3052 bytes long.
264282

265283
The library pads the payload by default. This is more secure but it decreases performance for both your server and your user's device.
266284

267285
#### Why is it more secure?
286+
268287
When you encrypt a string of a certain length, the resulting string will always have the same length,
269288
no matter how many times you encrypt the initial string. This can make attackers guess the content of the payload.
270289
In order to circumvent this, this library adds some null padding to the initial payload, so that all the input of the encryption process
271-
will have the same length. This way, all the output of the encryption process will also have the same length and attackers won't be able to
290+
will have the same length. This way, all the output of the encryption process will also have the same length and attackers won't be able to
272291
guess the content of your payload.
273292

274293
#### Why does it decrease performance?
294+
275295
Encrypting more bytes takes more runtime on your server, and also slows down the user's device with decryption. Moreover, sending and receiving the packet will take more time.
276296
It's also not very friendly with users who have limited data plans.
277297

278298
#### How can I disable or customize automatic padding?
299+
279300
You can customize automatic padding in order to better fit your needs.
280301

281302
Here are some ideas of settings:
303+
282304
* (default) `Encryption::MAX_COMPATIBILITY_PAYLOAD_LENGTH` (3052 bytes) for compatibility purposes with Firefox for Android
283305
* `Encryption::MAX_PAYLOAD_LENGTH` (4078 bytes) for maximum security
284306
* `false` for maximum performance
@@ -296,10 +318,12 @@ $webPush->setAutomaticPadding(true); // enable automatic padding to default maxi
296318
```
297319

298320
### Customizing the HTTP client
299-
WebPush uses [Guzzle](https://github.com/guzzle/guzzle). It will use the most appropriate client it finds,
321+
322+
WebPush uses [Guzzle](https://github.com/guzzle/guzzle). It will use the most appropriate client it finds,
300323
and most of the time it will be `MultiCurl`, which allows to send multiple notifications in parallel.
301324

302325
You can customize the default request options and timeout when instantiating WebPush:
326+
303327
```php
304328
<?php
305329

@@ -312,12 +336,13 @@ $clientOptions = [
312336
$webPush = new WebPush([], [], $timeout, $clientOptions);
313337
```
314338

315-
## Common questions
339+
## Common questions (FAQ)
316340

317341
### Is there any plugin/bundle/extension for my favorite PHP framework?
342+
318343
The following are available:
319344

320-
- Symfony:
345+
- Symfony:
321346
- [MinishlinkWebPushBundle](https://github.com/Minishlink/web-push-bundle)
322347
- [bentools/webpush-bundle](https://github.com/bpolaszek/webpush-bundle) (associate your Symfony users to WebPush subscriptions)
323348
- Laravel: [laravel-notification-channels/webpush](https://github.com/laravel-notification-channels/webpush)
@@ -326,19 +351,22 @@ The following are available:
326351
Feel free to add your own!
327352

328353
### What about security?
354+
329355
Payload is encrypted according to the [Message Encryption for Web Push](https://datatracker.ietf.org/doc/html/rfc8291) standard,
330356
using the user public key and authentication secret that you can get by following the [Web Push API](https://www.w3.org/TR/push-api/) specification.
331357

332-
Internally, WebPush uses the [WebToken](https://github.com/web-token) framework or OpenSSL to handle encryption keys generation and encryption.
358+
Internally, WebPush uses the [WebToken](https://github.com/web-token) framework and OpenSSL to handle encryption keys generation and encryption.
333359

334360
### How do I scale?
361+
335362
Here are some ideas:
336363

337364
1. Make sure MultiCurl is available on your server
338365
2. Find the right balance for your needs between security and performance (see above)
339366
3. Find the right batch size (set it in `defaultOptions` or as parameter to `flush()`)
340367

341368
### How to solve "SSL certificate problem: unable to get local issuer certificate"?
369+
342370
Your installation lacks some certificates.
343371

344372
1. Download [cacert.pem](https://curl.haxx.se/ca/cacert.pem).
@@ -347,25 +375,69 @@ Your installation lacks some certificates.
347375
You can also force using a client without peer verification.
348376

349377
### How to solve "Class 'Minishlink\WebPush\WebPush' not found"
378+
350379
Make sure to require Composer's [autoloader](https://getcomposer.org/doc/01-basic-usage.md#autoloading).
351380

352381
```php
353382
require __DIR__ . '/path/to/vendor/autoload.php';
354383
```
355384

356385
### I lost my VAPID keys!
386+
357387
See [issue #58](https://github.com/web-push-libs/web-push-php/issues/58).
358388

359-
### I'm using Firebase push notifications, how do I use this library?
360-
This library is not designed for Firebase push notifications.
361-
You can still use it for your web projects (for standard WebPush notifications), but you should forget any link to Firebase while using the library.
389+
### I'm using Google Cloud Messaging (GCM), how do I use this library?
390+
391+
This service does not exist anymore.
392+
It has been superseded by Google's Firebase Cloud Messaging (FCM) on May 29, 2019.
393+
394+
### I'm using Firebase Cloud Messaging (FCM), how do I use this library?
395+
396+
This library does not support Firebase Cloud Messaging (FCM).
397+
Old Chrome subscriptions (prior 2018 and VAPID) do use Legacy HTTP protocol by Firebase Cloud Messaging (FCM) which is [deprecated](https://firebase.google.com/support/faq#fcm-23-deprecation) since 2023 and will stop working in June 2024.
398+
The support for this outdated subscription is removed.
399+
400+
Please do not be confused as Legacy HTTP protocol and Web Push with VAPID use the identical endpoint URL:
401+
402+
> https://fcm.googleapis.com/fcm/send
403+
404+
Web Push with VAPID will remain available at this URL.
405+
No further action is currently required.
406+
407+
### How to send data?
408+
409+
The browser vendors do not allow to send data using the Push API without creating a notification.
410+
Use some alternative APIs like WebSocket/WebTransport or Background Synchronization.
362411

363412
### I need to send notifications to native apps. (eg. APNS for iOS)
413+
364414
WebPush is for web apps.
365415
You need something like [RMSPushNotificationsBundle](https://github.com/richsage/RMSPushNotificationsBundle) (Symfony).
366416

367417
### This is PHP... I need Javascript!
418+
368419
This library was inspired by the Node.js [web-push-libs/web-push](https://github.com/web-push-libs/web-push) library.
369420

421+
## Reference
422+
423+
### Examples, Notes and Overviews
424+
425+
- Google's [introduction to push notifications](https://web.dev/explore/notifications)
426+
- Mozilla [Push API (browser side)](https://developer.mozilla.org/en-US/docs/Web/API/Push_API)
427+
- Apple [Safari](https://developer.apple.com/documentation/usernotifications/sending_web_push_notifications_in_web_apps_and_browsers)
428+
- (Archive) Matthew Gaunt's [Web Push Book](https://web-push-book.gauntface.com)
429+
- (Archive) Mozilla's [ServiceWorker Cookbooks](https://github.com/mdn/serviceworker-cookbook/blob/master/push-payload/README.md) (don't mind the `server.js` file: it should be replaced by your PHP server code with this library)
430+
431+
### Internet Engineering Task Force (IETF)
432+
433+
- Generic Event Delivery Using HTTP Push [RFC8030](https://www.rfc-editor.org/rfc/rfc8030.html)
434+
- Message Encryption for Web Push [RFC8291](https://www.rfc-editor.org/rfc/rfc8291)
435+
- Voluntary Application Server Identification (VAPID) for Web Push [RFC8292](https://www.rfc-editor.org/rfc/rfc8292)
436+
437+
### W3C
438+
439+
- Working Draft [Push API](https://www.w3.org/TR/push-api/)
440+
370441
## License
442+
371443
[MIT](https://github.com/web-push-libs/web-push-php/blob/master/LICENSE)

0 commit comments

Comments
 (0)