FCM Web推送通知 - 无法获取令牌

时间:2018-05-08 12:44:08

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

在两天这么简单的事情上,这真的让我感到震惊:

我正在尝试实施FCM网络浏览器推送通知,我多次浏览了谷歌文档以及我在youtube上观看了所有官方视频。获取令牌非常容易,但由于某种原因,它会在Firebase的JS代码中崩溃。

这是我的HTML / JS代码:

<html>
    <head>
        <title>Web Push Test 2</title>
        <script src="/vendors/jquery/dist/jquery.min.js"></script>
        <script src="https://www.gstatic.com/firebasejs/4.13.0/firebase-app.js"></script>
        <script src="https://www.gstatic.com/firebasejs/4.13.0/firebase-messaging.js"></script>
    </head>
    <body>
        <button type="button" id="subscribe">Subscribe</button><br />
        <script src="https://www.gstatic.com/firebasejs/4.13.0/firebase.js"></script>       
        <script>
              var config = {
                apiKey: "AIzaSyBgYGotOm09UkhERqVPriV1XNhymxracno",
                authDomain: "******-b6f9c.firebaseapp.com",
                databaseURL: "https://******-b6f9c.firebaseio.com",
                projectId: "*******-b6f9c",
                storageBucket: "******-b6f9c.appspot.com",
                messagingSenderId: "333638181210"
              };
              firebase.initializeApp(config);

        if ('Notification' in window) {
            console.log("Notification is in window.");
            var messaging = firebase.messaging();
            messaging.usePublicVapidKey("BE0MvVZ0zyTYGmeNIdj4A8XZZ50OKaZL90xmXbIVfufcMuPb0lAUC99426aBPrAEPHAWYeMbOTpHbcM3OiySEcs");
            messaging.onMessage(function(payload) {
              console.log("Message received. ", payload);
            });

            messaging.onTokenRefresh(function() {
              messaging.getToken().then(function(refreshedToken) {
                console.log('Token refreshed.');
                setTokenSentToServer(false);
                sendTokenToServer(refreshedToken);
              }).catch(function(err) {
                console.log('Unable to retrieve refreshed token ', err);
                showToken('Unable to retrieve refreshed token ', err);
              });
            });

            if (Notification.permission === 'granted') {
                console.log("Permission is granded.");
                subscribe();
            }

            $('#subscribe').on('click', function () {
                console.log("Subscribe fired.");
                subscribe();
            });
        }

        function subscribe() {
            messaging.requestPermission().then(function() {
                  console.log('Notification permission granted.');            
                  messaging.getToken().then(function(currentToken) {
                    if (currentToken) {
                      sendTokenToServer(currentToken);
                    } else {
                      console.log('No Instance ID token available. Request permission to generate one.');
                      setTokenSentToServer(false);
                    }
                  }).catch(function(err) {
                    console.log('An error occurred while retrieving token. ', err);
                    showToken('Error retrieving Instance ID token. ', err);
                    setTokenSentToServer(false);
                  });
            }).catch(function(err) {
              console.log('Unable to get permission to notify.', err);
            });
        }

        window.is_sentToServer = false
        function setTokenSentToServer(sent) {
            window.is_sentToServer = sent
        }

        function showToken(currentToken) {
          console.log('Token: '+currentToken);
        }

        function sendTokenToServer(currentToken) {
            $.post('/?c=push&a=save_subscription', {token: currentToken}, function(data){
                console.log('Token added...');
                setTokenSentToServer(true);
            });
        }
    </script>
</body>

当我运行该页面时,出现以下错误:

An error occurred while retrieving token.  TypeError: Cannot read property 'buffer' of undefined

firebase JS的崩溃点就在这里:

https://www.gstatic.com/firebasejs/messaging/dist/index.esm.js

function isTokenStillValid(pushSubscription, publicVapidKey, tokenDetails) {
if (!isArrayBufferEqual(publicVapidKey.buffer, tokenDetails.vapidKey.buffer)) {
    return false;
}
var isEndpointEqual = pushSubscription.endpoint === tokenDetails.endpoint;
var isAuthEqual = isArrayBufferEqual(pushSubscription.getKey('auth'), tokenDetails.auth);
var isP256dhEqual = isArrayBufferEqual(pushSubscription.getKey('p256dh'), tokenDetails.p256dh);
return isEndpointEqual && isAuthEqual && isP256dhEqual;

}

因此,到目前为止我可以理解 - tokenDetails.vapidKey变量未定义,这就是为什么它无法读取缓冲区大小,但问题是 - 为什么?

我仔细检查了我提供的所有密钥是否有效,但无法弄清楚这里可能出现的问题......

非常感谢任何可以帮助我解决这个问题的人

我在localhost上运行该测试,因为它在原始YouTube教程中显示,我没有忘记创建firebase-messaging-sq.js,如下所示:

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

var config = {
  apiKey: "AIzaSyBgYGotOm09UkhERqVPriV1XNhymxracno",
  authDomain: "*****-b6f9c.firebaseapp.com",
  databaseURL: "https://******-b6f9c.firebaseio.com",
  projectId: "*******-b6f9c",
  storageBucket: "*****-b6f9c.appspot.com",
  messagingSenderId: "333638181210"
};
firebase.initializeApp(config);

const messaging = firebase.messaging();

messaging.usePublicVapidKey("BE0MvVZ0zyTYGmeNIdj4A8XZZ50OKaZL90xmXbIVfufcMuPb0lAUC99426aBPrAEPHAWYeMbOTpHbcM3OiySEcs");

messaging.setBackgroundMessageHandler(function (payload) {
  console.log('Handling background message ', payload);

  return self.registration.showNotification(payload.notification.title, {
    body: payload.notification.body
  });
});

1 个答案:

答案 0 :(得分:0)

这是Firebase SDK中的一个错误。有关该问题的详尽说明,请参见the PR here

修复程序将在SDK的5.0.2版本中。它应该在今天或明天晚些时候出来。

如果您不想更新,则解决方法是清除您的应用程序数据。这将强制SDK重新生成令牌。您可以通过打开开发者控制台,转到应用程序选项卡,选择&#34;清除存储&#34;然后在Chrome中执行此操作。从左侧菜单中,单击&#34;清除网站数据&#34;底部的按钮。