使用 FCM 的服务人员在 Chrome 中获取数据

Posted

技术标签:

【中文标题】使用 FCM 的服务人员在 Chrome 中获取数据【英文标题】:Service workers with FCM get data in Chrome 【发布时间】:2017-01-05 22:46:43 【问题描述】:

我正在尝试使用 ServiceWorkers 和 GCM 在 Chrome 中实现推送通知。

通知工作正常,但事件的推送功能为空 (self.addEventListener('push', function(event))。

接下来是我的代码,工作正常,收到通知,但没有收到数据。

注册:

<script>
        document.addEventListener('DOMContentLoaded', function () 

            /*navigator.serviceWorker.getRegistration().then(function(r)  
             r.unregister();
             );*/

           // document.querySelector("#enablepush").addEventListener('click', function (e) 
                //if(Notification.permission !== 'granted') 
                Notification.requestPermission().then(function (permission) 
                    if (permission === 'granted' && 'serviceWorker' in navigator) 
                        navigator.serviceWorker.register('myworker.js').then(initialiseState);
                     else 
                        console.log('service worker not present');
                    
                );
                // 
          //  );
            //get subscription token if already subscribed
            if (Notification.permission === 'granted') 
                navigator.serviceWorker.ready.then(function (registration) 
                    registration.pushManager.getSubscription().then(function (subscription) 
                        getToken(subscription);
                    );
                );
            
        );



        function SalirPush()
        
            console.log("Si registro ha sido cancelado");
            navigator.serviceWorker.getRegistration().then(function (r) 
                r.unregister();
            );

            navigator.serviceWorker.ready.then(function (reg) 
                reg.pushManager.getSubscription().then(function (subscription) 
                    subscription.unsubscribe().then(function (successful) 
                        // You've successfully unsubscribed
                    ).catch(function (e) 
                        // Unsubscription failed
                    )
                )
            );
        


        function initialiseState() 

            //check if notification is supported or not
            if (!('showNotification' in ServiceWorkerRegistration.prototype)) 
                console.warn('Notificaiton are not supported');
                return;
            
            //check if user has blocked push notification
            if (Notification.permission === 'denied') 
                console.warn('User has blocked the notification');
            
            //check if push messaging is supported or not
            if (!('PushManager' in window)) 
                console.warn('Push messaging is not supported');
                return;
            

            //subscribe to GCM
            navigator.serviceWorker.ready.then(function (serviceWorkerRegistration) 
                //call subscribe method on serviceWorkerRegistration object
                serviceWorkerRegistration.pushManager.subscribe(userVisibleOnly: true)
                        .then(function (subscription) 
                            getToken(subscription);
                            var met = JSON.stringify(subscription);
                            console.log("Mensaje", met);
                        ).catch(function (err) 
                    console.error('Error occured while subscribe(): ', err);
                );
            );
        

        function getToken(subscription) 
            console.log(subscription);
            var token = subscription.endpoint.substring(40, subscription.endpoint.length);
            //document.querySelector("#token").innerhtml = token;
            try
            
                $("#apikey").val(token);
            catch (e)
            

            
        
    </script>

接下来是我的workers.js;

self.addEventListener('push', function(event)     
 var url = "/push/json-data.php?param=(This is the event data info)";
  event.waitUntil(  
    fetch(url).then(function(response)   
      if (response.status !== 200)   
        // Either show a message to the user explaining the error  
        // or enter a generic message and handle the
        // onnotificationclick event to direct the user to a web page  
        console.log('Looks like there was a problem. Status Code: ' + response.status);  
        throw new Error();  
      

      // Examine the text in the response  
      return response.json().then(function(data)   
        if (data.error || !data.notification)   
          console.log('The API returned an error.', data.error);  
          throw new Error();  
          
        var title = data.notification.title;  
        var message = data.notification.message;  
        var icon = data.notification.icon;  

        return self.registration.showNotification(title,   
          body: message,  
          icon: icon,  
          data: 
            url: data.notification.url
            
        );  
      );  
    ).catch(function(err)   
      console.log('Unable to retrieve data', err);

      var title = 'An error occurred';
      var message = 'We were unable to get the information for this push message';  
      var icon = 'img/design19.jpg';  
      var notificationTag = 'notification-error';  
      return self.registration.showNotification(title,   
          body: message,  
          icon: icon,  
          tag: notificationTag  
        );  
    )  
  );  
);

// The user has clicked on the notification ...
self.addEventListener('notificationclick', function(event)   
  console.log(event.notification.data.url);
  // android doesn't close the notification when you click on it  
  // See: http://crbug.com/463146  
  event.notification.close();

  // This looks to see if the current is already open and  
  // focuses if it is  
  event.waitUntil(
    clients.matchAll(  
      type: "window"  
    )
    .then(function(clientList)   
      for (var i = 0; i < clientList.length; i++)   
        var client = clientList[i];  
        if (client.url == '/' && 'focus' in client)  
          return client.focus();  
        
      if (clients.openWindow) 
        return clients.openWindow(event.notification.data.url);  
      
    )
  );
);

接下来发送推送通知,我使用这个 PHP:

    <?php

$estado=$_GET["estado"];
$idtoken=$_GET["id"];
$op=$_GET["op"];

if ($op != "")

sendFCM("My App","Hi to all", $idtoken,$estado);

function sendFCM($titulo,$mess,$id,$estado) 
    echo "Recibi: $mess , $id, $estado";
    $data = array('status'=> $estado,'mensaje'=>'"'.$mess.'"','titulo'=>'"'.$titulo.'"');
$url = 'https://fcm.googleapis.com/fcm/send';
$fields = array (
        'to' => $id,
        'notification' => array (
                "body" => $mess,
                "title" => $titulo,
                "icon" => "myicon",
            "color"=> "#0000ff",
            "sound" => "default"

        ),
    'data' => $data,
    'payload' => $data
);

$fields = json_encode ( $fields );
$headers = array (
        'Authorization: key=' . "MyGoogleKey",
        'Content-Type: application/json'
);

$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_URL, $url );
curl_setopt ( $ch, CURLOPT_POST, true );
curl_setopt ( $ch, CURLOPT_HTTPHEADER, $headers );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $fields );

$result = curl_exec ( $ch );
curl_close ( $ch );
echo ($result);


?>

感谢您的帮助。

【问题讨论】:

我有同样的问题,但我对 /push/json-data.php 页面感到困惑。 我的 json-data.php 是为了可以在我的数据库中查阅通知周围的所有信息。但我需要在“事件”中接收一个数据(ID 或任何其他信息以在我的数据库中进行咨询) 可能是***.com/questions/38992034/…, ***.com/questions/37088397/… 【参考方案1】:

在您的推送事件中使用event.data.json().data

self.addEventListener('push', function(event) 
    event.waitUntil(
        self.registration.pushManager.getSubscription().then(function(subscription) 
            console.info(event.data.json().data);
        );
    );  
);

【讨论】:

以上是关于使用 FCM 的服务人员在 Chrome 中获取数据的主要内容,如果未能解决你的问题,请参考以下文章

如何获得 FCM 代币?

如何使用 Google FCM 和 Microsoft azure 作为托管服务器从 chrome for android 上的 PWA 发送推送通知

Chrome Firebase 云消息 - 未注册

根据 OneSignal 的用户数据库直接发送 Web 推送 (Chrome - GCM/FCM) 通知

FCM(Firebase 云消息传递):Firebase 推送通知在 Firefox 中显示,但在 Chrome 中不显示

使用 php 向 ios 设备发送带有 fcm 令牌的远程通知