如何从请求中检索通知/数据?

时间:2016-10-20 23:13:50

标签: javascript firebase-cloud-messaging

我正在尝试使用Firebase云消息传递基本通知,但我无法终身了解如何在通知中包含任何实际内容。

我首先从基本上可以找到here的精简版本开始。我有三个文件,一个manifest.json,看起来像这样:

{ "gcm_sender_id": "my sender id" }

index.html,如下所示:

<html>                                                                                                  
  <head><link rel="manifest" href="manifest.json"></head>
  <body>
    <div id="endpoint-show">There doesn't seem to be an endpoint right now</div>

    <script src="https://www.gstatic.com/firebasejs/3.5.0/firebase-app.js"></script>                    
    <script src="https://www.gstatic.com/firebasejs/3.5.0/firebase-messaging.js"></script>              
    <script>                                                                                            
      var config = {apiKey: "my key", authDomain: "my domain", messagingSenderId: "my id"};                                                                                                
      firebase.initializeApp(config);                                                                   

      const messaging = firebase.messaging();                                                           
      messaging.requestPermission()                                                                     
        .then(function() { console.log('Notification permission granted.'); })                          
        .catch(function(err) { console.log('Unable to get permission to notify. ', err); });            

      navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {                          
        serviceWorkerRegistration.pushManager.subscribe({userVisibleOnly: true})                        
          .then(function(subscription) {                                                                
            document.getElementById("endpoint-show").innerHTML = "<p>" + subscription.endpoint.split('/\').slice(-1)[0] + "</p>";                                                                               
          })                                                                                            
        });                                                                                             
      navigator.serviceWorker.register('./service-worker.js')                                           
    </script>                                                                                           
  </body>                                                                                               
<html>

和service-worker.js,看起来像:

self.addEventListener('push', function(event) {
  console.log('Received a push message', event);
  event.waitUntil(self.registration.showNotification("title", { body: "body" }));
});

这似乎是关于注册推送通知订阅以及建立服务工作者来处理它们所需的最少代码量。

然后我使用curl命令发送通知,如here所示。即,使用那些特定标题集发布到https://fcm.googleapis.com/fcm/send,并且包含“too”字段的正文等于我的idex.html显示的字段。这是有效的,因为我在计算机上收到标题为“标题”和正文“正文”的通知。

但是这里是我被困住的地方:我可以通过此请求发送的唯一数据似乎是通知发生的事实,而不是任何其他(实际)数据。我链接的第一个示例只是硬编码通知,我自己的代码也是如此,但我希望能够发送带有任意数据的请求。文档here似乎表明我应该能够设置请求的datanotification字段,并获取包含该数据的通知,但似乎不上班。我已经在我正在制作的请求中设置了两个字段,所以整个事情看起来像这样(我使用邮递员发送):

POST /fcm/send HTTP/1.1
Host: fcm.googleapis.com
Content-Type: application/json
Authorization: key=my key
Cache-Control: no-cache
Postman-Token: some token

{
    "notification": {
        "body": "notification body",
        "title": "notification title"
    },
    "data": {
        "body": "data body",
        "title": "data title"
    },
    "to" : "my endpoint"
}

但我无法弄清楚如何实际检索任何数据。我的服务工作者捕获的事件不包含任何此类数据。我所看到的所有文档似乎都没有描述如何通过网络实际获取这些数据,仅在Android或iOS上,但显然有可能因为许多网站实施动态通知。

我怀疑我对所有这些工作方式有一些基本的误解,因为我对任何类型的网络开发都没有什么经验,所以这并不奇怪。如果我想做的事情是不可能的,或者以完全不同的方式完成,请告诉我。

重申一下,这正是我要做的事情:

  1. 发送请求(无论是我写的网络服务器还是firebase)。

  2. 我的Chrome上会显示一条通知,其中包含该请求中的信息。

1 个答案:

答案 0 :(得分:1)

您似乎将新的firebase消息传递库与旧式服务工作者代码混合在一起。

获得许可后,您需要致电getToken API

  // service.js
  // after request permission is successful
  // Get Instance ID token. Initially this makes a network call, once retrieved
  // subsequent calls to getToken will return from cache.
  messaging.getToken()
    .then(function(currentToken) {
      if (currentToken) {
        sendTokenToServer(currentToken);
        updateUIForPushEnabled(currentToken);
      } else {
        // Show permission request.
        console.log('No Instance ID token available. Request permission to generate one.');
        // Show permission UI.
        updateUIForPushPermissionRequired();
        setTokenSentToServer(false);
      }
   })
   .catch(function(err) {
     console.log('An error occurred while retrieving token. ', err);
     showToken('Error retrieving Instance ID token. ', err);
     setTokenSentToServer(false);
   });

它值得商榷,但您还需要使用filename作为firebase-messaging-sw.js创建服务工作。可以找到参考here

在这个服务工作者中,你需要做这样的事情:

// firebase-messaging-sw.js
'use strict';
console.log('Starting service worker');

if( 'function' === typeof importScripts) {

  importScripts('https://www.gstatic.com/firebasejs/3.5.0/firebase-app.js');
  importScripts('https://www.gstatic.com/firebasejs/3.5.0/firebase-messaging.js');
  importScripts('core/decoder.js');

  // Initialize the Firebase app in the service worker by passing in the
  // messagingSenderId.
  firebase.initializeApp({
    'messagingSenderId': 'YOUR-SENDER-ID'
  });

  // Retrieve an instance of Firebase Messaging so that it can handle background
  // messages.
  const messaging = firebase.messaging();


  messaging.setBackgroundMessageHandler(function(payload) {
    var shinyData = payload || {};

    console.log('[firebase-messaging-sw.js] Received background message ', payload, shinyData);

    return self.registration.showNotification(shinyData.title, {
      body: shinyData.body,
      icon: shinyData.icon,
      data: {url: shinyData.tag}
    })
  });
}

您可能会发现this gist我创建了有用的内容。