如何使用Service Worker和FCM实现推送通知

14

我正在尝试在 Chrome 上使用 Firebase 的服务工作者来实现推送通知。我的 Web 应用程序中有一个清单文件和一个 sw.js 文件。我已经在 Firebase 中创建了一个项目,并测试了注册和发送通知。所有这些都很好,只是当接收通知时,数据为 null。我不明白为什么,也没有任何有用的资源(据我所知!)。下面是我的服务工作者文件:

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);
  });
}

清单文件.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 以其他方式完成的? 提前感谢。


您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Marco Castelluccio
我也有这个问题。 - ihsansat
目前正在解决同一个问题。不认为Firebase目前支持我们使用serviceWorkers获得的webPush。 - pascalwhoop
2
Firebase仅支持Chrome应用/扩展程序。 Chrome中的Web Push目前使用GCM基础设施运作。 https://firebase.google.com/docs/cloud-messaging/chrome/client - Xeos
2个回答

5
根据此文,从Chrome 50开始,你可以使用Chrome通知版本发送数据。
在Chrome 50之前,推送消息不能包含任何有效负载数据。当服务工作者中的“push”事件触发时,你只知道服务器正在试图告诉你一些内容,但不知道具体是什么。然后,你需要向服务器发出跟进请求并获取要显示的通知详细信息,这在网络条件差的情况下可能会失败。
现在,在Chrome 50(以及桌面版Firefox的当前版本)中,你可以发送一些随意的数据,并将其与推送一起发送,以便客户端避免进行额外的请求。但是,伴随着强大的功能而来的是巨大的责任,因此所有有效负载数据都必须加密。
对于你目前的实现,你可以像这样做:
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 中的 worker 的 registration id 参数传递,并获得该特定 id 的通知。 希望这有所帮助!


非常感谢您告知我现在已经可以了。 - TheSabby
什么是apiPath? - Sanjay Radadiya
API路径是请求URL,它提供了通知数据。 - doubt

0

根据这个教程,目前你无法向GCM发送任何数据:

Chrome中Push API的当前实现的缺点是,你不能在推送消息中发送任何数据。不行,什么都不能发。原因是,在未来的实现中,负载数据必须在发送到推送消息端点之前在你的服务器上进行加密。这样,无论是哪个推送提供者的端点,都无法轻易查看推送消息的内容。这也可以防止其他漏洞,如HTTPS证书验证不足和你的服务器与推送提供者之间的中间人攻击。然而,这种加密尚未得到支持,因此在此期间,您需要执行获取所需信息以填充通知的操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接