如何将 service worker 与 FCM 一起用于推送通知

How to use service worker with FCM for Push Notifications

我正在尝试将 Service Worker 与 Firebase 结合使用以在 chrome 上实施推送通知。我的网络应用程序中有一个清单文件和一个 sw.js 文件。我在 Firebase 中创建了一个项目,并且测试了注册和发送通知。这一切都很好,除了在收到通知时数据为空。我不明白为什么,也没有任何有用的资源(据我所知!)。 这是我的服务工作者文件:

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/logo.svg',
      tag: 'my-tag'
  }));
});

这是我的 main.js 文件:

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js').then(function(registration) {
    // Registration was successful
    console.log('ServiceWorker registration successful with scope: ',    registration.scope);
    registration.pushManager.subscribe({
      userVisibleOnly: true
    }).then(function(sub) {
      console.log('endpoint:', sub.endpoint);
    }).catch(function(e) {

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

Manifest.json:

{
  "name": "APPNAME",
  "gcm_sender_id": "SENDERID"
}

cURL 请求:

curl --header "Authorization: key=APIKEY" -application/json" https://fcm.googleapis.com/fcm/send -d "{\"registration_ids\":[\"REGISTRATIONID\"],\"notification\":{\"title\":\"test\",\"body\":\"testing\"},\"data\":{\"title\":\"erse\"}}"

来自 sw.js 的推送事件的控制台日志:

我没有收到我在请求中发送的任何数据。这是用 firebase 以其他方式完成的吗? 提前致谢。

根据this tutorial,您目前无法向 GCM 发送任何数据:

A downside to the current implementation of the Push API in Chrome is that you can’t send any data with a push message. Nope, nothing. The reason for this is that in a future implementation, payload data will have to be encrypted on your server before it’s sent to a push messaging endpoint. This way the endpoint, whatever push provider it is, will not be able to easily view the content of the push message. This also protects against other vulnerabilities like poor validation of HTTPS certificates and man-in-the-middle attacks between your server and the push provider. However, this encryption isn’t supported yet, so in the meantime you’ll need to perform a fetch to get information needed to populate a notification.

根据 this,您可以使用 chrome 通知版本发送数据 chrome 版本 50 及以上。

Prior to Chrome 50, push messages could not contain any payload data. When the ‘push’ event fired in your service worker, all you knew was that the server was trying to tell you something, but not what it might be. You then had to make a follow up request to the server and obtain the details of the notification to show, which might fail in poor network conditions.

Now in Chrome 50 (and in the current version of Firefox on desktop) you can send some arbitrary data along with the push so that the client can avoid making the extra request. However, with great power comes great responsibility, so all payload data must be encrypted.

对于您当前的实施,您可以这样做:

self.addEventListener('push', function(event) {

var apiPath = '<apiPath>';
event.waitUntil(registration.pushManager.getSubscription().then(function (subscription){
    
    return fetch(apiPath).then(function(response){
        if(response.status !== 200){
            throw new Error();
        }

        return response.json().then(function(data){
            var title = data.title;
            var message = data.body;
            var icon = data.icon;
            var tag = data.tag;
            var url = data.url;
            return self.registration.showNotification(title,{
               body: message,
               icon: icon,
               tag: tag,
               data: url
            });
        })
    }).catch(function(err){
        
    })
    
}));
return;
});

对于任何可以与特定用户相关的特定通知,您可以在 api url 中传递工作人员的注册 ID 参数并获取该特定 ID 的通知。 希望这对您有所帮助!