[PWA] Enable Push Notification in your web app

1. Clone the project:

git clone https://github.com/GoogleChrome/push-notifications.git

 

2. install the web server:

 

3. Open the web server, set app folder as current folder, toggle the switch button to restart the server.

Go localhost:8887 you will see the push noticifiation app.

 

4. Register the service worker: app/js/main.js

复制代码
if ('serviceWorker' in navigator) {
  console.log('Service Worker is supported');
  navigator.serviceWorker.register('sw.js').then(function() {
    return navigator.serviceWorker.ready;
  }).then(function(reg) {
    console.log('Service Worker is ready :^)', reg);
      // TODO
  }).catch(function(error) {
    console.log('Service Worker error :^(', error);
  });
}
复制代码

The sw.js is located in app folder.

 

5. Add code to sw.js

复制代码
console.log('Started', self);

self.addEventListener('install', function(event) {
  self.skipWaiting();
  console.log('Installed', event);
});

self.addEventListener('activate', function(event) {
  console.log('Activated', event);
});

self.addEventListener('push', function(event) {
  console.log('Push message received', event);
  // TODO
});
复制代码

There there is a service worker activate. the new servie worker will wait unit the old service worker removed from the browser(hard refersh / close the current tab and open a new one). 

In 'Install' event, we tell 

self.skipWaiting()

So once anything changed in the code, refresh the browser, new servie worker will replace the old one and start work.

 

6. Make a project on the Google developer console

For now, if you want to have push notifications on Chrome, you need to create a project on developer console. FireFox doesn't need to do that. And in the future, you won't need to do that, it will support by default.

Push notifications from a web app need a backend service to handle messaging. Chrome currently uses Google Cloud Messaging (GCM) for this, though the eventual goal is for Chrome and GCM to support the Web Push Protocol. Other browsers are free to use other services.

  • From the Google APIs list, select Google Cloud Messaging. And Enable it.
  • Enter the key name
  • Click create. get your key
  • Go to IAM & Admin, get the project number

 

7. Add a mainfest

A manifest is a JSON file that provides information about your web app, including Push Notifications configuration.

app/manifest.json:

{
  "name": "Push Notifications codelab",
  "gcm_sender_id": "593836075156"
}

"gcm_sender_id" is what you got "project number" before.

 

Link in index.html to mainfest.json:

复制代码
<!DOCTYPE html>
<html>
<head>

  <title>Push Notification codelab</title>
  <link rel="manifest" href="manifest.json">
</head>

<body>

  <h1>Push Notification codelab</h1>

  <script src="js/main.js"></script>

</body>
</html>
复制代码

 

8. Subscribe to Push Notifications

Modify the js/main.js:

复制代码
'use strict';

if ('serviceWorker' in navigator) {
    console.log('Service Worker is supported');
    navigator.serviceWorker.register('sw.js').then(function() {
        return navigator.serviceWorker.ready;
    }).then(function(reg) {
        console.log('Service Worker is ready :^)', reg);
        reg.pushManager.subscribe({userVisibleOnly: true}).then(function(sub) {
            console.log('endpoint:', sub.endpoint);
        });
    }).catch(function(error) {
        console.log('Service Worker error :^(', error);
    });
}
复制代码

This code uses the ServiceWorkerRegistration object's pushManager to subscribe to messages for the gcm_sender_id you added to the manifest previously.

You must pass a {userVisibleOnly: true} argument to the subscribe() method. This tells the browser that a notification will always be shown when a push message is received. Currently it's mandatory to show a notification.

 

9. Refresh your browser and you will see:

And you can find you "endPoint" in you console.

 

10. Send a request from the command line for GCM to push a message.

To get GCM to push a notification to your web client, you need to send GCM a request that includes the following:

    • The public API key that you created, which looks like this:

      AIzaSyAc2e8MeZHA5NfhPANea01wnyeQD7uVY0c

      GCM will match this with the Project Number you got from the Google Developer Console to use as thegcm_sender_id value in the manifest.
    • An appropriate Content-Type header, such as application/json.
    • An array of subscription IDs, each of which corresponds to an individual client app. That's the last part of the subscription endpoint URL, and looks like this: 

      APA91bHMaA-R0eZrPisZCGfwwd7z1EzL7P7Q7cyocVkxBU3nXWed1cQYCYvFglMHIJ40kn-jZENQ62UFgg5QnEcqwB5dFZ-AmNZjATO8QObGp0p1S6Rq2tcCuUibjnyaS0UF1gIM1mPeM25MdZdNVLG3dM6ZSfxV8itpihroEN5ANj9A26RU2Uw

Put together: (You need to get your own key, this would NOT work for you)E

curl --header "Authorization: key=AIzaSyAVOc3rC1jBZQ5AHg0_0mZjJ6GzgZiiZD" --header "Content-Type: application/json" https://android.googleapis.com/gcm/send -d "{\"to\":\"cHOJzWtzgqQ:APA91bG6n-paaecj4CmGygeKrr2u7XX_0iOMM4kPNZz9YiZhpXyAMuy0dhtw_shqNtNyeU9HN5v2eGtrfW6nyCBEDm7ZdoOPi2k6q3LhCilw3JCrhmBpa8PIlcPQZmHFQF68dvR41tWN\"}"

install cURL and try the command.

 

You will send the notificaiton in your browser.

But really, this is not useful, we want the custom message

 

10. Show the message:

in sw.js:

复制代码
console.log('Started', self);

self.addEventListener('install', function(event) {
    self.skipWaiting();
    console.log('Installed', event);
});

self.addEventListener('activate', function(event) {
    console.log('Activated', event);
});

self.addEventListener('push', function(event) {
    console.log('Push message', event);

    var title = 'Push message';

    event.waitUntil(
        self.registration.showNotification(title, {
            body: 'The Message',
            icon: 'images/icon.png',
            tag: 'my-tag'
        }));
});
复制代码

Try again, you will see:

Better, icon, title and message body.

 

11. Handle notification clicks

In this step you will add code to enable an action (such as navigating to a web page) when a user clicks a notification.

复制代码
self.addEventListener('notificationclick', function(event) {
  console.log('Notification click: tag', event.notification.tag);
  // Android doesn't close the notification when you click it
  // See http://crbug.com/463146
  event.notification.close();
  var url = 'https://youtu.be/gYMkEMCHtJ4';
  // Check if there's already a tab open with this URL.
  // If yes: focus on the tab.
  // If no: open a tab with the URL.
  event.waitUntil(
    clients.matchAll({
      type: 'window'
    })
    .then(function(windowClients) {
      console.log('WindowClients', windowClients);
      for (var i = 0; i < windowClients.length; i++) {
        var client = windowClients[i];
        console.log('WindowClient', client);
        if (client.url === url && 'focus' in client) {
          return client.focus();
        }
      }
      if (clients.openWindow) {
        return clients.openWindow(url);
      }
    })
  );
});
复制代码

This code listens for a notification click, then opens a web page — in this example, a YouTube video.

This code checks all window clients for this Service Worker; if the requested URL is already open in a tab, focus on it — otherwise open a new tab for it.

 

12. Unsubscribe from notifications

a client unsubscribes from notifications by calling the unsubscribe() method of the PushSubscriptionobject.

Modify the index.html add 

复制代码
<!DOCTYPE html>
<html>
<head>

  <title>Push Notification codelab</title>

  <link rel="manifest" href="manifest.json">

</head>

<body>

<h1>Push Notification codelab</h1>

<p>This page must be accessed using HTTPS or via localhost.</p>

<button disabled>Subscribe</button>

<script src="js/main.js"></script>

</body>
</html>
复制代码

Add a Subscribe/Unsubscribe button to your app.

 

Modify the main.js:

复制代码
var reg;
var sub;
var isSubscribed = false;
var subscribeButton = document.querySelector('button');

if ('serviceWorker' in navigator) {
    console.log('Service Worker is supported');
    navigator.serviceWorker.register('sw.js').then(function() {
        return navigator.serviceWorker.ready;
    }).then(function(serviceWorkerRegistration) {
        reg = serviceWorkerRegistration;
        subscribeButton.disabled = false;
        console.log('Service Worker is ready :^)', reg);
    }).catch(function(error) {
        console.log('Service Worker Error :^(', error);
    });
}

subscribeButton.addEventListener('click', function() {
    if (isSubscribed) {
        unsubscribe();
    } else {
        subscribe();
    }
});

function subscribe() {
    reg.pushManager.subscribe({userVisibleOnly: true}).
    then(function(pushSubscription){
        sub = pushSubscription;
        console.log('Subscribed! Endpoint:', sub.endpoint);
        subscribeButton.textContent = 'Unsubscribe';
        isSubscribed = true;
    });
}

function unsubscribe() {
    sub.unsubscribe().then(function(event) {
        subscribeButton.textContent = 'Subscribe';
        console.log('Unsubscribed!', event);
        isSubscribed = false;
    }).catch(function(error) {
        console.log('Error unsubscribing', error);
        subscribeButton.textContent = 'Subscribe';
    });
}
复制代码

In this code, you set the value of the ServiceWorkerRegistration object reg when the Service Worker installs, which is then used in the subscribe() function to subscribe to push messaging.

Everytime you subscribe and unsubscribe, the endpoint will change, so you need to reconfig it.

The subscribe() function creates the PushSubscription object sub which can be used by theunsubscribe() function.

Remember, the client gets a new registration ID every time it re-subscribes, so you will need to adjust requests to GCM accordingly.

 

 13. Add Actions Button to the notification:

复制代码
//sw.js

self.addEventListener('push', function(event) {
    console.log('Push message', event);

    var title = 'Push message';

    event.waitUntil(
        self.registration.showNotification(title, {
            body: 'The Message',
            icon: 'images/icon.png',
            tag: 'my-tag',
            actions: [
                {action: 'like', title: 'Like', icon: 'images/like.png'},
                {action: 'setting', title: 'Setting', icon: 'images/setting.png'}
            ]
        }));
});
复制代码

 

14. Handle action click:

According to different action type you can do different stuff, here just open different youtube video.

复制代码
self.addEventListener('notificationclick', function(event) {
    console.log('Notification click: tag', event.notification.tag);
    event.notification.close();
    if(event.action === "like"){
        var url = "https://www.youtube.com/watch?v=DC8FsIdVi9Y";
    }else if(event.action === "setting"){
        var url = "https://www.youtube.com/watch?v=K9QY8faD6sY";
    }else{
        // Click the notification body
        var url = 'https://youtu.be/gYMkEMCHtJ4';
    }

    openWindow(event, url);
});

function openWindow(event, url){
    event.waitUntil(

        clients.matchAll({
            type: 'window'
        })
            .then(function(windowClients) {
                console.log('WindowClients', windowClients);
                for (var i = 0; i < windowClients.length; i++) {
                    var client = windowClients[i];
                    console.log('WindowClient', client);
                    if (client.url === url && 'focus' in client) {
                        return client.focus();
                    }
                }
                if (clients.openWindow) {
                    return clients.openWindow(url);
                }
            })
    );
}
复制代码

 

15. Dismiss the notification:

If user click the close button, then it means user might not want to be distrubed. Then you might need to tell the server, not be send this user notification again.

self.addEventListener('notificationclose', function(event) {
    var data = event.notification.data;
    console.log('Notification Close', data);
    event.waitUntil(
        // Tell server not to send me notification again.
      //  fetch('/api/close-notif?id='+data.id)
    )
});

 

posted @   Zhentiw  阅读(974)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示