Firebase 云消息传递的 getToken() 仅在我省略 usePublicVapidKey 方法时才有效,为啥?

Posted

技术标签:

【中文标题】Firebase 云消息传递的 getToken() 仅在我省略 usePublicVapidKey 方法时才有效,为啥?【英文标题】:Firebase Cloud Messaging's getToken() only works if I omit the usePublicVapidKey method, why?Firebase 云消息传递的 getToken() 仅在我省略 usePublicVapidKey 方法时才有效,为什么? 【发布时间】:2018-09-24 19:10:12 【问题描述】:

我在实施 Firebase for Firebase Cloud Messaging (FCM) 时遇到了具体问题:

正如您在下面的代码中看到的,//messaging.usePublicVapidKey("<MY VAPID KEY IN HERE>"); 当前已被注释。 VAPID 密钥是在服务器终端中通过以下命令获得的:web-push generate-vapid-keys。如果我取消注释此行,当我调用 notification_permission() 时,我会在控制台中收到此错误:

代码:“messaging/token-subscribe-failed”,

消息:“请求缺少所需的身份验证凭据。需要 OAuth 2 访问令牌、登录 cookie 或其他有效的身份验证凭据。请参阅https://developers.google.com/identity/sign-in/web/devconsole-project。”,

李>

stack: "FirebaseError: Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project. at https://www.gstatic.com/firebasejs/4.12.1/firebase-messaging.js:6:8316"

这是我当前的index.html 文件:

<script src="https://www.gstatic.com/firebasejs/4.12.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.12.1/firebase-messaging.js"></script>
<script>
var config = 
    apiKey: "<MY FIREBASE API KEY>",
    authDomain: "<MY FIREBASE PROJECT ID>.firebaseapp.com",
    databaseURL: "https://<MY FIREBASE PROJECT ID>.firebaseio.com",
    projectId: "<MY FIREBASE PROJECT ID>",
    storageBucket: "<MY FIREBASE PROJECT ID>.appspot.com",
    messagingSenderId: "<MY FIREBASE SENDER ID?>"
;
firebase.initializeApp(config);

//messaging app
const messaging = firebase.messaging();

//vapid
//messaging.usePublicVapidKey("<MY VAPID KEY IN HERE>");

//register service worker
navigator.serviceWorker.register('firebase-messaging-sw.js').then(function(registration) 
    console.log('Service Worker Registered!', registration);
).catch(function(err) 
    console.error('Service Worker registration failed', err);
);
</script>

这是我调用的 javascript 函数,用于获取用户接收通知的权限并获取用户的令牌:

<script>
function notification_permission() 
    messaging.requestPermission().then(function(permission) 
        console.log('Notification permission granted.', permission);
        messaging.getToken().then(function(current_token) 
            if(current_token) 
                //update user token
                // update_token(current_token);
                console.log('token', current_token);
             else 
                // you don't have permission to show notifications
                // detect whether they are blocked or not, then show your custom UI
            
        ).catch(function(err) 
            // retrieving token failed, analyze the error
            console.error('retrieving token failed, analyze the error', err);
        );
    ).catch(function(err) 
        console.error('Unable to get permission to notify.', err)
    );

</script>

我的manifest.json 文件中已经有这个:


    "gcm_sender_id": "103953800507",
    "serviceworker": 
        "src": "firebase-messaging-sw.js",
        "scope": "/"
    

我对此配置的具体问题是:

    是否可以使用web-push generate-vapid-keys 只获取一次 VAPID 密钥,并对所有用户请求使用相同的 VAPID 密钥?

    为什么使用 VAPID 密钥时getToken() 方法会失败?

    VAPID 方法是可选的吗?使用它有什么好处?

感谢您的帮助!

【问题讨论】:

我有一个相反的情况,当我省略 VAPID 密钥时,我无法获取令牌,它给出了与您提到的需要“OAUTH2”相同的错误如果我添加一个 VAPID 密钥,那么我可以拿一个令牌,但是当我发送通知时,它没有收到任何消息。我正在搜索,但找不到任何相关文档。我应该使用 VAPID 密钥吗?如果是,不接收消息可能有什么问题,或者我不应该使用该密钥,那么我应该怎么做才能在不需要 OAUTH2 的情况下获取令牌?我希望你已经解决了。 【参考方案1】:

1) 是的。

2) 因为令牌与 firebase 帐户有关,而不是与 vapid 密钥有关。绕过firebase你无法获得任何令牌。

3) 在不使用 firebase 时使用 vapid 很有用。

【讨论】:

以上是关于Firebase 云消息传递的 getToken() 仅在我省略 usePublicVapidKey 方法时才有效,为啥?的主要内容,如果未能解决你的问题,请参考以下文章

TypeError:messaging.getToken 不是函数

IOS Web 浏览器上的 Firebase 消息传递

Firebase 云消息传递重复通知

Firebase 云消息传递消息日志

Firebase 云消息传递 - 有多个主题 - 没有消息重复

Firebase 云消息传递通知图像定价