在发送推送通知时未调用messaging.onMessage()(JavaScript)

时间:2017-11-03 14:06:45

标签: javascript firebase push-notification firebase-cloud-messaging

我发现了一个与Stackoverflow类似的问题,但不幸的是它没有得到解答。

我尝试使用FCM向网络发送推送通知。当我把Android设备的令牌和通知成功传递给所有令牌时,我已经设置了我的应用服务器并且工作正常。但是,在将通知发送到Web时,不会调用Web上的onMessage()函数。

我的代码是:

<script src="https://www.gstatic.com/firebasejs/4.6.0/firebase.js"></script>
       <script>
         // Initialize Firebase
         var config = {
           apiKey: "xxxxxxxxx",
           authDomain: "xxxxxxxx",
           databaseURL: "xxxxxxx",
           projectId: "xxxxxxxxxxxx",
           storageBucket: "xxxxxxxxx",
           messagingSenderId: "xxxxxxxxx"
         };
         firebase.initializeApp(config);

           //Get Token
          const messaging = firebase.messaging();
          messaging.requestPermission()
           .then(function () {
               console.log('Have permission');
               return messaging.getToken();
           })
        .then(function (token) {
            console.log(token);
        })
          .catch(function (err) {
              console.log('Error occurred');
          });

          messaging.onMessage(function (payload) {
              console.log('onMessage', payload);
          })

firebase-messaging-sw.js代码代码:

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

var config = {
apiKey: "xxxxxxxxx",
authDomain: "XXXXXXXXXX",
databaseURL: "XXXXXXXXXX",
projectId: "XXXXXXXXXX",
storageBucket: "XXXXXXXXX",
messagingSenderId: "XXXXXXXXXX"
};

firebase.initializeApp(config);

const messaging = firebase.messaging();

我无法弄清楚出了什么问题。

1 个答案:

答案 0 :(得分:0)

我发现这个话题在我试图开始的时候记录得很糟糕,我几乎放弃了几次,所以希望其他读这篇文章的人可能觉得这很有用。

推送通知的整个概念变得更加混乱,因为实际上涉及不同的Web API,它们一起工作,这通常不明确。如果你使用VAPID或FCM,还有争论吗?如何使用FCM VAPID? Blah blah blah blah。

因此,首先您需要处理检查/获取用户通知权限,创建/更新订阅,保存令牌等。如果您获得令牌/订阅,那么您将全部设置为向客户端发送数据(这是Push API的东西。)

从技术上讲,如果您的用户永远不会离开您的网站,这就是您所需要的,但显然他们会这样做,这就是您需要服务工作者的原因。服务工作者可以在用户无法打开您的站点的情况下接收您的推送数据,然后对其执行操作。 (这是Push / Service Worker API交叉)。

最后,您希望您的用户看到您向他们发送的消息,对吗? Push API将您的消息数据提供给服务工作者,但您仍然必须处理该数据。您可能希望显示通知,因此您需要通知API。

现在,查看您的代码,您似乎正在做前端的第一部分并为您的用户获取令牌,但您的服务工作者实际上没有代码,因此它什么都不做。我知道Firebase有一些自定义事件处理程序,但标准的Web推送也应该有效。

您需要开始使用的是服务工作者代码中推送事件的基本处理程序,如下所示:

self.addEventListener('push', function(event) {
    const push = event.data.json();
    const title = push.data.title;
    const options = JSON.parse(push.data.options);
    event.waitUntil(registration.showNotification(title, options));
});

关于这一点的好处是保持代码简单而不是硬编码服务工作者中的任何通知选项,它允许服务器端代码动态地自定义每个通知的行为和外观。服务工作者实际上只是解析推送有效负载的JSON输入并使用有效负载内的选项创建通知

您可以找到Notification API here的可用选项列表,它们仍在更改,但截至目前,以下PHP示例与上述服务工作者代码一起将通过Firebase发送功能完备的通知:

$push['to'] = $SUBSCRIBED-FCM-TOKEN;
$push['data']['title'] = 'Here is my title';
$push['data']['options']['body'] = 'and here is the body message';
$push['data']['options']['badge'] = '/images/chaticon.png';
$push['data']['options']['requireInteraction'] = true;
$push['data']['options']['tag'] = 'notification-tag';
$push['data']['options']['icon'] = '/images/icons/256.jpg';
$push['data']['options']['vibrate'] = array(500,150,500,150,500);
$push['data']['options']['image'] = '/images/logo.jpg';
$push['data']['options']['actions'] = array(array('action' => 'accept-action', 'title' => 'Yes', 'icon' => '/images/icons/yes.jpg' ), array('action' => 'reject-action', 'title' => 'No', 'icon' => '/images/icons/no.jpg'));
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://fcm.googleapis.com/fcm/send");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($push));
curl_setopt($ch, CURLOPT_POST, 1);
$headers = array();
$headers[] = "Content-Type: application/json";
$headers[] = "Authorization: key=$SERVER-KEY-FROM-FIREBASE-CONSOLE";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
curl_close ($ch);

显然,这只是一个让您前进的基本示例,您可以选择添加获取事件以响应点击您的通知操作等,以执行进一步的操作,分析或其他任何操作。您还可以根据用户是否已经在您的网站上来改变行为。