如何将网络推送通知发送给所有用户(PWA / Progressive-Web-App)?

时间:2019-05-03 17:20:07

标签: javascript push-notification service-worker progressive-web-apps web-push

如何通过网络推送npm-package向所有用户或浏览器或“添加到主屏幕-PWA”发送推送通知

我有一名服务人员,注册并订阅了推送通知。

我有一个按钮,单击它后,我将使用有效负载进行POST API调用,以使用后端的web-push npm-package推送通知。

因此,当您单击按钮时,Web-push仅向当前浏览器发送通知,而不向在其他设备中打开的其他浏览器发送通知,而不是向我做了“添加到主屏幕(PWA-Icon)”的设备发送通知

这是我的代码:-

生成publicKey和privateKey

npm install -g web-push
web-push generate-vapid-keys

存储生成的publicKey和privateKey

const publicKey = 'BLmmA...';
const privateKey = '-9n9v...';

使用publicKey订阅pushManager,然后将pushManager中的generate-subscription-object保存到数据库文件“ /db/subscription.json”中。以下代码来自sw.js文件。

function urlB64ToUint8Array(base64String) {
  const padding = '='.repeat((4 - (base64String.length % 4)) % 4);
  const base64 = (base64String + padding).replace(/\-/g, '+').replace(/_/g, '/');

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

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

const saveSubscription = subscriptionJSON => {
  // Saving generated-subscription-object from pushManager into the DataBase file (/db/subscription.json).
  fetch('/save-subscription', {
    method: 'post',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(subscriptionJSON),
  })
    .then(res => {
      return res.json();
    })
    .then(res => {
      console.log('saveSubscription -> res:: ', res);
    });
}

self.addEventListener('activate', event => {
  try {
    self.registration.pushManager.subscribe({
      userVisibleOnly: true,
      applicationServerKey: urlB64ToUint8Array(publicKey),
    }).then(subscriptionJSON => {
      saveSubscription(subscriptionJSON);
    });
  } catch (err) {
    console.log('Error in self.addEventListener(activate)', err);
  }
});

文件“ /db/subscription.json”包含这样的数据

  {
    "endpoint": "https://fcm.googleapis.com/fcm/send/e5mo...",
    "expirationTime": null,
    "keys": {
      "p256dh": "BDZl...",
      "auth": "K72l..."
    }
  }

单击执行POST API调用的按钮,即可将通知推送给所有用户或浏览器或“添加到主屏幕PWA”。

  sendNotification = () => {
    axios
      .post('/send-notification', { payload: 'Dummy Notification' })
      .then(res => {
        console.log('/send-notification -> res:: ', res);
      })
      .catch(err => {
        console.log('/send-notification -> err:: ', err);
      });
  };

“ /保存订阅”和“ /发送通知”的API服务

const webpush = require('web-push');

const publicKey = 'BLmmA...';
const privateKey = '-9n9v...';

app.post('/save-subscription', (req, res) => {
  const subscriptionData = req.body || {};

  // Storing subscription-object into "/db/subscription.json" file.
  fs.writeFile('/db/subscription.json', JSON.stringify(subscriptionData, null, 2), err => {
    if (err) {
      return res.status(500).send({ err, subscriptionJSON: null });
    }

    return res.status(200).send({ subscriptionJSON });
  }
}

app.post('/send-notification', (req, res) => {
  // Retrieving stored subscription-object from the file.
  const subscriptionJSON = require('/db/subscription.json');
  const payload = _get(req, 'body.payload', '');
  const options = {
    vapidDetails: {
      subject: 'mailto: example@gmail.com',
      publicKey,
      privateKey,
    },
    contentEncoding: 'aes128gcm',
  }

  // Pushing notification to all Users or Browsers or Add-To-Home-Screen-PWA's.
  webpush
    .sendNotification(subscriptionJSON, payload, options)
    .then(notification => {
      return res.status(_get(notification, 'statusCode') || 201).send({ notification, subscriptionJSON });
    })
    .catch(err => {
      return res.status(_get(err, 'statusCode') || 500).send({ err, notification: null });
    });
}

0 个答案:

没有答案