简体   繁体   中英

Firebase Cloud Messaging AJAX POST in JavaScript

I have the following code for TESTING PURPOSES:

$.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 () { },
});

This always results in the following response with a 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"
  }
}

What am I doing wrong?

In a very broad sense, what you're doing wrong is trying to call the FCM APIs from a web browser client. FCM messages are intended to be sent from a backend server under your total control. The authorization token that you need to send is going to effectively have admin privileges to send messages to any and all of your users, and you don't want to give that up to clients , as it's massive security issue.

From the 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.

In other words, you're not supposed to give clients access to send messages with your privileged service account credentials. The rest of that page of documentation describes how to actually do the world of authorizing the send request.

In the docs we linked in comments: https://firebase.google.com/docs/cloud-messaging/js/first-message

Under Retrieve Registration Token , you see this code:

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

You'll notice the sendTokenToServer() function, that's not their function, that's supposed to be yours. You call their getToken() and in the promise you take the result and send it up, would look like this:

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

Then on the server, you'd receive that, and store it, likely in a database, related to their profile information.

Then, either at that moment, or, at a later time, you can query your database for those you want to notify, grab that token, and in conjunction with your access token stored securely on your server , you can then send the notification from there.

Typically, NodeJS, PHP, Python, or Ruby. As events happen, or on a schedule, your server can send notifications like this:

<?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
]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM