Solara07
Solara07

Reputation: 21

Has Google FCM stopped accepting HTTP requests?

I was previously able to send curl messages to http://fcm.googleapis.com/fcm/send

However now I get 403:Forbidden Error

However, the same curl script works if I change http to https.

This restriction seems to have been put in place yesterday. My source of messages is an arduino which can only handle HTTP and not HTTPS.

Does anybody know if I can still send HTTP requests to FCM via another route?

Upvotes: 0

Views: 838

Answers (3)

Camila Alvarado
Camila Alvarado

Reputation: 573

Set http (http://fcm.googleapis.com/fcm/send) by https (https://fcm.googleapis.com/fcm/send) on API URL.

Upvotes: 0

Solara07
Solara07

Reputation: 21

Ok, I now have a workaround solution for my Arduino ESP Project to use HTTPS with Google Firebase Cloud Messaging.

i thought I would share it for others stuck in the same rut.

In a nutshell, I created a free PHP website, which offered curl functionality, and scripted an HTTP API to accept HTTP requests and forward them onto Google FCM using an HTTPS Connection.

Here are my solution steps:

  1. Sign up to free account aon https://www.000webhost.com
  2. Create/Manage a free subdomain website eg "yourname" (www.yourname.000webhostapp.com)
  3. Dashboard -> Tools -> FileManager -> Upload Files
  4. in your "public_html" folder create a new file named "api.php"
  5. Paste the PHP code below into this file, and Save & Close
  6. Replace your Arduino old code http references for "http://fcm.googleapis.com/fcm/send" with "http://yourname.000webhostapp.com/api.php"

  7. Job done!

    <?php 
    // This API allows Arduino to send HTTPS FCM messages
    // Takes raw data from the incoming HTTP request
    $json = file_get_contents('php://input');
    
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send');
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $json);
    
    // build the outgoing headers
    $hdr_out = array();
    $hdr_out[] = 'Content-Type: application/json';
    // read incoming header to extract just the auth key
    foreach (getallheaders() as $name => $value) { 
        //echo "$name: $value\n"; 
        if (strtoupper($name) == "AUTHORIZATION") {
            $hdr_out[] = 'Authorization: '. $value;
        }
    } 
    curl_setopt($curl, CURLOPT_HTTPHEADER, $hdr_out);
    
    $result = curl_exec($curl);
    
    if ($result) {
        $response_code= curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
        curl_close($curl);
        http_response_code($response_code);
    }
    else {
        echo "API Failure";
        http_response_code(500);
    }
    ?>
    

Its my first attempt at writing PHP code, so feel free to suggest any improvements.

Upvotes: 1

nPn
nPn

Reputation: 16758

I also have an Arduino project (ESP8266 based) that is also sending http (not https) posts to http://fcm.googleapis.com/fcm/send. that has also stopped working.

I was able to confirm via Postman that requests sent to http://fcm.googleapis.com/fcm/send fail with a 403 (Forbidden) response.

I was able to get something working again by adding a fingerprint to the call to the begin method.

http.begin("https://fcm.googleapis.com/fcm/send", "F6:84:98:95:E5:6B:AC:EC:17:79:74:BF:1A:4B:E0:7E:FA:C8:EC:E9");

I was able to find the fingerprint using this site https://www.grc.com/fingerprints.htm

My actual app however is crashing with the the above update, so I still need to dig into this some more. I think there is a bug in the HttpClient that has already been fixed and I am just not picking it up.

Update

The issue with my full Arduino app crashing was due to the https request using too much memory (esp8266's don't have a lot of memory). I looked at a few options that could reduce the memory requirements, but ultimately I decided to go with a similar, but slightly different approach than what Solara07 posted.

Since I already had a raspberry pi running on my network I decided to use that as a proxy. I installed trafficserver on the raspberry pi and added the following two lines to the /etc/trafficserver/remap.config

map http://192.168.86.77/fcm/send https://fcm.googleapis.com/fcm/send
reverse_map https://fcm.googleapis.com/fcm/send http://192.168.86.77/fcm/send

The required change to my arduino code was the following: Change:

http_.begin("http://fcm.googleapis.com/fcm/send");

To:

http_.begin("192.168.86.77", 8080, "http://192.168.86.77/fcm/send");

where http_ is the instance of the HTTPClient and 192.168.86.77 is the private internal address of my raspberry pi

More details and an answer to some problems I had implementing this can be found here.

Upvotes: 0

Related Questions