JavaScript 中的 Firebase 云消息传递 AJAX POST

Firebase Cloud Messaging AJAX POST in JavaScript

我有以下用于测试目的的代码:

$.ajax({
  url: 'https://fcm.googleapis.com/v1/projects/[PROJECT]/messages:send',
  type: 'POST',
  headers:{
    "Authorization":"Bearer "+[Access Token from FireBase Auth]
  },
  contentType:"application/json",
  data: {
    "message":{
      "token": [TOKEN from messaging.getToken],
      "notification" : {
        "body" : "This is an FCM notification message!",
        "title" : "FCM Message",
        }
     }
  },
  success: function () { },
  error: function () { },
});

这总是会导致以下响应为 401()...

{
  "error": {
    "code": 401,
    "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
    "status": "UNAUTHENTICATED"
  }
}

我做错了什么?

从广义上讲,您做错的是试图从 Web 浏览器客户端调用 FCM API。 FCM 消息旨在从您完全控制的后端服务器发送。您需要发送的授权令牌将有效地具有管理员权限,可以向您的任何和所有用户发送消息,并且您不想将其交给客户,因为这是一个巨大的安全问题。

来自documentation

Requests sent to FCM from your app server or trusted environment must be authorized. The FCM HTTP v1 API uses a short-lived OAuth 2.0 access token generated for a service account associated with your Firebase project. The legacy protocols use long-lived API keys retrieved from the Firebase console. In both cases, you must add the required credential to each message request sent to FCM.

换句话说,您不应该允许客户端使用您的特权服务帐户凭据发送消息。该文档页面的其余部分描述了如何实际执行授权发送请求的世界。

在我们在评论中链接的文档中:https://firebase.google.com/docs/cloud-messaging/js/first-message

检索注册令牌 下,您会看到此代码:

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);
});

您会注意到 sendTokenToServer() 功能,那不是他们的功能,应该是您的功能。你打电话给他们的 getToken() 并承诺你会收到结果并将其发送出去,看起来像这样:

function sendTokenToServer(currentToken) {
    $.post({
        url: 'yourServer.com/some_token_receiving_endpoint',
        type: 'post',
        data: {token: currentToken}
    });
}

然后在服务器上,您会收到并存储它,很可能在数据库中,与他们的个人资料信息相关。

然后,无论是在那一刻,还是稍后,您都可以在数据库中查询要通知的人,获取该令牌,并与安全存储在 上的访问令牌结合使用您的服务器,然后您可以从那里发送通知。

通常是 NodeJS、PHP、Python 或 Ruby。当事件发生或按计划发生时,您的服务器可以发送这样的通知:

<?php
// Get some http client service  for your language
$client = new GuzzleHttp\Client();

// Get your user or users (with their tokens that you've stored)
$user = Db.someQueryReturningUser();

// Your message
$jsonData = '{
    "message":{
        "token": [TOKEN from messaging.getToken],
        "notification" : {
            "body" : "This is an FCM notification message!",
            "title" : "FCM Message",
        }
    }
 }';

// Send Mesage
$client->post('https://fcm.googleapis.com/v1/projects/[PROJECT]/messages:send',
[ 
    'headers' => [
        'Authorization' => 'Bearer ' . [Access Token from FireBase Auth]
    ],
    'json' => $jsonData
]);