在客户端和服务器端管理推送通知的订阅

时间:2018-09-04 09:24:58

标签: javascript push-notification notifications workbox


我清除了以前有关如何使用workbox push notification文档中给出的代码的所有问题,以向您展示我更清楚地找到的解决方案。

在向您展示代码之前,我将解释我花了很长时间来理解。您通常使用与Service Worker配合使用的三个文件。就我而言,server.jsindex.jssw.js。当浏览器获得显示您的站点所需的所有文件时,我还获得了index.js文件。该文件以navigator.serviceWorker.register('sw.js')启动服务工作者。然后,它测试用户是否已经接受接收通知。最后,它检查订阅是否存在并对其进行管理。
订阅部分非常重要且难以管理。使用swRegistration.pushManager.subscribe(),我们将获得一个sub对象。该对象包含端点 auth p256th 。这些信息非常重要,我们需要将其发送到服务器以将其存储到数据库中。 fetch()元素可以做到这一点。通过这种方式,我们将能够在未来向我们带标签的用户发送通知。

您需要了解的最后一件事以及如何创建私有和公共Vapid密钥。要生成它,请在您的终端中显示 server.js 中我privateVapidKey变量下面的 console.log 。然后像将server.js一样将两个结果都复制粘贴到变量中,然后将publicsVapidKey复制粘贴到 index.js 文件中。
server.js:

var express = require('express');
var app = express();
var https = require('https');
var fs = require('fs');
var webPush = require('web-push');
var bodyParser = require('body-parser');    

https.createServer({
  key: fs.readFileSync('key_localhost2.pem'),
  cert: fs.readFileSync('cert_localhost2.pem'),
  passphrase: 'localhost',
}, app).listen(8080);

//*****************************************************************
//-------------------------- TEMPLATES --------------------------
//*****************************************************************
//moteur de modèles ou de templates
app.set('view engine', 'ejs');

//*****************************************************************
//-------------------------- MIDDLEWARE --------------------------
//*****************************************************************    
app
  .use('/static', express.static(__dirname + '/public'))
  .use(express.static(__dirname + '/public/js'))
  .use(bodyParser.json());

//*****************************************************************
//--------------------------- ROUTES ------------------------------
//*****************************************************************   
app.get('/', function (request, response) {
  response.render('./pages/index.ejs');
});

var publicVapidKey = "BKwLqQWMQpLfSNGb-VXCsAPE1H5o7Oh3VxDiEIqWWOm2OdAoFPqr9K9WI7dKKtjYYHLTKm7tjJO04091pDXZiJs"
var privateVapidKey = "483sZs2cZUxSQegGKKOZXLl_b7_ywBF_qJO77gXFsHE"
//console.log('Publics keys : ' + vapidKeys.publicKey)
//console.log('Private key : ' + vapidKeys.privateKey)

webPush.setVapidDetails(
  'mailto:localhost:8080',
  publicVapidKey,
  privateVapidKey
);

var pushSubscription; 

app.post('/subscription_push_notification', function (req, resp) {
  pushSubscription = req.body;
  console.log(pushSubscription)

  //I'm able to save this information into my database
  endpointVal = req.body.endpoint;
  authVal = req.body.keys.auth;
  p256dhVal = req.body.keys.p256dh;

  setTimeout(function () {

    if (endpointVal) {

      var payload = 'Here is a payload!';

      webPush.sendNotification(
        pushSubscription,
        payload
      ).catch(function (err) {
        console.log(err);
      });
    }
  }, 2000)

  resp.json({});
});

index.js:

window.addEventListener('load', function () {

    //*********************************************************
    // Start SW, permission notification, register subscribe
    //*********************************************************
    if ('serviceWorker' in navigator) {

        //+++++++++++++++++++++++++++++
        //Register Service worker
        navigator.serviceWorker.register('sw.js')
            .then(function (swRegistration) {

                //Ask to notification permission
                displayNotification();

                var publicVapidKey = "BKwLqQWMQpLfSNGb-VXCsAPE1H5o7Oh3VxDiEIqWWOm2OdAoFPqr9K9WI7dKKtjYYHLTKm7tjJO04091pDXZiJs";
                var applicationServerKey = urlBase64ToUint8Array(publicVapidKey);

                //Manage push notifiaction
                swRegistration.pushManager.getSubscription().then(function (sub) {
                    if (sub === null) {
                        // Update UI to ask user to register for Push
                        console.log('Not subscribed to push service!');

                        swRegistration.pushManager.subscribe({
                            userVisibleOnly: true,
                            applicationServerKey: applicationServerKey
                        }).then(function (sub) {
                            // We have a subscription, update the database
                            console.log('Endpoint URL: ', sub.endpoint);
                            fetch('/subscription_push_notification', {
                                method: 'POST',
                                body : JSON.stringify(sub),
                                headers: {
                                    'content-type':'application/json'
                                }
                            });
                        }).catch(function (e) {

                            if (Notification.permission === 'denied') {
                                console.warn('Permission for notifications was denied');
                            } else {
                                console.error('Unable to subscribe to push', e);
                            }
                        });

                    } else {
                        // We have a subscription, update the database
                        console.log('Subscription object: ', sub);
                        fetch('/subscription_push_notification', {
                            method: 'POST',
                            body : JSON.stringify(sub),
                            headers: {
                                'content-type':'application/json'
                            }
                        });

                    }
                });
            })
            .catch(function (err) {
                console.log('Service Worker registration failed: ', err);

            })

    }


    //*********************************************************
    // Function ask to notification permission
    //*********************************************************
    function displayNotification() {

        if (Notification.permission === 'granted') {
            //Mean, the notification is accepted.
            console.log('Notification accepted...');

        } else if (Notification.permission === "blocked" || Notification.permission === "denied") {
            // the user has previously denied notification. Can't reprompt.
            console.log('Notification blocked...');

        } else {
            // show a prompt to the user
            console.log('Prompt to accept notification');

            Notification.requestPermission();
        }
    }


    //*********************************************************
    // Transform public Vapid key
    //*********************************************************
    function urlBase64ToUint8Array(base64String) {
        const padding = '='.repeat((4 - base64String.length % 4) % 4);
        const base64 = (base64String + padding)
            .replace(/\-/g, '+')
            .replace(/_/g, '/');

        const rawData = window.atob(base64);
        const outputArray = new Uint8Array(rawData.length);

        for (let i = 0; i < rawData.length; ++i) {
            outputArray[i] = rawData.charCodeAt(i);
        }
        return outputArray;
    }

});

sw.js:

importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.4.1/workbox-sw.js');

if (workbox) {
  console.log(`Yay! Workbox is loaded `);
} else {
  console.log(`Boo! Workbox didn't load `);
}


//*********************************************************
// Save file from site to work in offline mode
//*********************************************************
workbox.precaching.precacheAndRoute([
  { url: '/', revision: '383676' },
  { url: '/static/css/style.css', revision: '383677' },
  { url: '/static/js/index.js', revision: '383678' },
]);

//*********************************************************
// The notification click event
//*********************************************************
//Inform when the notification close/hide from the window 
self.addEventListener('notificationclick', function (e) {
  console.log('notification was clicked')
  var notification = e.notification;
  var action = e.action;

  if (action === 'close') {
    notification.close();
  } else {
    clients.openWindow('https://www.google.fr');
  };
});


//*********************************************************
// Handling the push event in the service worker
//*********************************************************
self.addEventListener('push', function (e) {
  console.log('Hi man !!!')

  var options = {
    body: e.data.text(),
    icon: '/static/img/logo_menu.png',
    vibrate: [100, 50, 100],
    data: {
      dateOfArrival: Date.now(),
      primaryKey: '2'
    },
  };
  e.waitUntil(
    self.registration.showNotification('Hello world!', options)
  );
});

0 个答案:

没有答案