Skip to content

Commit 931d387

Browse files
committed
Improve README and service-worker.js code
1 parent b335978 commit 931d387

File tree

4 files changed

+65
-75
lines changed

4 files changed

+65
-75
lines changed

PushMessageFromServer.js

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,36 @@
11
// https://developers.google.com/web/updates/2015/05/notifying-you-of-changes-to-notifications
22
// https://felixgerschau.com/web-push-notifications-tutorial/
33
// https://developers.google.com/web/fundamentals/codelabs/push-notifications
4-
const webpush = require('web-push');
4+
const webPush = require('web-push');
55

66
// VAPID keys should be generated only once with:
7-
// const vapidKeys = webpush.generateVAPIDKeys();
7+
// const vapidKeys = webPush.generateVAPIDKeys();
88
// console.log(vapidKeys);
99

1010
const vapidKeys = {
1111
publicKey: 'BHG9NdYdfiCIx7xUS8u2CMhtDD-GWHb6QYuSZ908NZYZHhJEjGjcX0yTjHrWx7gDICmCEUORrLmw3uwOGBqzm2s',
1212
privateKey: 'wDf6oqOkg0SQ3FD8NU9ZNrwVZWIGBfm1gPgp6QNXWjk'
1313
};
1414

15-
webpush.setVapidDetails(
15+
webPush.setVapidDetails(
1616
'mailto:example@yourdomain.org',
1717
vapidKeys.publicKey,
1818
vapidKeys.privateKey
1919
);
2020

21-
// This is the sample output of calling JSON.stringify on a PushSubscription
21+
// This is an sample subscription object that we get after subscript on browser
22+
const pushSubscription =
23+
{
24+
"endpoint": "",
25+
"keys": {
26+
"p256dh": "",
27+
"auth": ""
28+
}
29+
}
2230

23-
// const pushSubscription =
24-
// endpoint: '.....',
25-
// keys: {
26-
// auth: '.....',
27-
// p256dh: '.....'
28-
// }
29-
// };
31+
const payload = {
32+
title: `Hello at ${(new Date()).toISOString()}`,
33+
url: 'https://www.dotnetthailand.com'
34+
};
3035

31-
const payload = { title: `Hello at ${(new Date()).toISOString()}` };
32-
webpush.sendNotification(pushSubscription, JSON.stringify(payload));
36+
webPush.sendNotification(pushSubscription, JSON.stringify(payload));

README.md

Lines changed: 33 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,55 +3,46 @@
33
## How to run the project locally
44
- Open a new terminal session.
55
- CD to the root folder of the project and run `yarn` to install all Node packages.
6-
- Then run `yarn start` to start a project and automatically launch a browser.
7-
- Click `Subscribe Web Push` and copy a subscription object in text box.
8-
- Use subscription object in a server side to send push notification.
9-
10-
```sh
11-
yarn create react-app web-push-api-example --template typescript
12-
```
13-
14-
- Required Node.js version >= 14
15-
16-
# Get subscription object
17-
- For the main project in .NET Thailand repository, it can be accessed as http://www.dotnetthailand.com/web-push-api-example/.
6+
- Then run `yarn start` to start the project and automatically launch a browser.
7+
- Click `Subscribe Web Push` and copy a subscription JSON object in a text box.
8+
- Use subscription object on a server side to send push notification.
9+
- This project requires Node.js version >= 14.
1810

1911

2012
# Send push notification from a server
21-
- Set a push subscrition object in `PushMessageFromServer` that we get after a user's subscribed web push.
22-
- Execute the following command:
13+
- Set a push subscription object that we get after a user's subscribed web push in `PushMessageFromServer.js`
14+
- Then execute the following command:
2315
```sh
24-
node PushMessageFromServer.js
16+
$ node PushMessageFromServer.js
2517
```
2618

27-
## Notification does not always show as banner.
28-
Turn of focus assist
29-
30-
server
31-
private/public key
32-
33-
client
34-
public key
35-
36-
load register service background
37-
38-
subscribe to server with public key
39-
send subscription object to store on server as identity
40-
41-
import web-push
42-
43-
const vapIdKey = push.generateVAPIDKeys(); to get public and private keys
44-
setVapidDetails()
45-
sendNotification
46-
47-
serviceWorker to handle receive notification
48-
49-
skip waiting in application tab
19+
# Trouble shooting
20+
## Notification does not always show as banner on Windows.
21+
- Try to turn off focus assist.
22+
## No push notification message at all
23+
- You may need to manually update service worker. Open Chrome developer tool with ctrl+shift+i keys and then go to application tab.
24+
Then click Service Workers node > Skip waiting service worker.
25+
26+
# Key concept
27+
- Generate publish and private key public and private keys with the following code
28+
```js
29+
const vapIdKeys = webPush.generateVAPIDKeys();
30+
const vapidKeys = webPush.generateVAPIDKeys();
31+
console.log(vapidKeys);
32+
```
33+
- Use a public key in subscription script (App.tsx)
34+
- User subscribes web push with subscription script.
35+
- Use both public, private keys and subscription object on server script (PushMessageFromServer.js) to send push to a user.
36+
- Subscription object is what we store in a database. It is an identity of a subscribed user.
37+
- Use service worker script (service-worker.js) to handle push notification and customize how to show it to a user
38+
- You can test push with a localhost and do need to deploy to public URL
39+
40+
# Get subscription object on a published website
41+
- For the main project in .NET Thailand repository, it can be accessed as http://www.dotnetthailand.com/web-push-api-example/.
5042

51-
Useful articles for .NET Web Push
52-
- https://www.pluralsight.com/guides/html5-desktop-notifications-with-react?fbclid=IwAR1NzrQNDYSZJxKLMxWVVWes_eulWauBqa63F6Z47dDznNBL9ARiCQ26wOs
43+
# Useful articles for .NET Web Push
44+
- https://www.pluralsight.com/guides/html5-desktop-notifications-with-react
5345
- https://blog.elmah.io/how-to-send-push-notifications-to-a-browser-in-asp-net-core/
5446
- https://www.bartvanuden.com/2018/01/23/push-notifications-to-your-pwa-with-asp-net-core-2-0-and-aurelia/
5547
- https://www.tpeczek.com/2017/12/push-notifications-and-aspnet-core-part.html
56-
- https://stackoverflow.com/a/47617427/1872200
57-
-
48+
- https://stackoverflow.com/a/47617427/1872200

public/service-worker.js

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,16 @@ self.addEventListener('push', (event) => {
1717
actions: [
1818
{
1919
// https://developers.google.com/web/ilt/pwa/introduction-to-push-notifications#the_notificationclick_event
20-
action: 'open-product-link',
21-
title: `Open product's link`,
20+
action: 'open-a-link',
21+
title: `Open a link`,
2222
//icon: '/demos/notification-examples/images/action-1-128x128.png'
2323
}
2424
],
2525
data: {
2626
url: payload.url
2727
}
28+
29+
// Chrome does not support sound attribute https://github.com/GoogleChromeLabs/airhorn/issues/18
2830
}; // end of options
2931

3032
// https://javascript.info/promise-basics
@@ -36,31 +38,25 @@ self.addEventListener('push', (event) => {
3638
});
3739

3840
// https://stackoverflow.com/a/63917373/1872200
39-
// aync function is a function that synchronously returns a promise
41+
// async function is a function that synchronously returns a promise
4042
async function showNotificationAsync(payload, options) {
4143
await self.registration.showNotification(payload.title, options);
4244
}
4345

4446
// https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/notificationclick_event#examples
4547
self.addEventListener('notificationclick', (event) => {
4648
const { action, notification } = event;
47-
console.log(JSON.stringify(notification, null, 2))
48-
4949
notification.close();
50-
if (action === 'open-product-link') {
51-
// https://developer.mozilla.org/en-US/docs/Web/API/Clients/openWindow#return_value
5250

51+
if (action === 'open-a-link') {
52+
// https://developer.mozilla.org/en-US/docs/Web/API/Clients/openWindow#return_value
5353
// https://web-push-book.gauntface.com/common-notification-patterns/
54-
clients.openWindow(notification.data.url);
54+
//clients.openWindow(notification.data.url);
55+
event.waitUntil(openLink(notification.data));
5556
}
56-
57-
// event.waitUntil(openProductLink(action, data));
5857
});
5958

60-
async function openProductLink(action, data) {
61-
notification.close();
62-
if (action === 'open-product-link') {
63-
// https://developer.mozilla.org/en-US/docs/Web/API/Clients/openWindow#return_value
64-
await clients.openWindow(data.url);
65-
}
59+
async function openLink(data) {
60+
// https://developer.mozilla.org/en-US/docs/Web/API/Clients/openWindow#return_value
61+
await clients.openWindow(data.url);
6662
}

src/App.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,12 @@ export default function App() {
1212
}, []);
1313

1414
const handleSubscribeWebPush = async () => {
15-
const sw = await navigator.serviceWorker.ready;
15+
const serviceWorker = await navigator.serviceWorker.ready;
1616
const publicKey = 'BHG9NdYdfiCIx7xUS8u2CMhtDD-GWHb6QYuSZ908NZYZHhJEjGjcX0yTjHrWx7gDICmCEUORrLmw3uwOGBqzm2s';
17-
const push = await sw.pushManager.subscribe({
17+
const push = await serviceWorker.pushManager.subscribe({
1818
userVisibleOnly: true,
1919
applicationServerKey: publicKey,
2020
});
21-
console.log(`push subscription :\n\n${JSON.stringify(push, null, 2)}`);
2221
setSubscription(JSON.stringify(push, null, 2));
2322
}
2423

@@ -32,7 +31,7 @@ export default function App() {
3231
Subscript Web Push
3332
</button>
3433
<div>
35-
<textarea rows={10} style={style} value={subscription} />
34+
<textarea rows={10} style={style} value={subscription} readOnly={true} />
3635
</div>
3736
</div>
3837
);

0 commit comments

Comments
 (0)