2

I'm attempting to push a notification to a specific Android device using a heroku PHP server. I'm not having any luck in doing so, however.

I can push a notification through the firebase console just fine (i.e. the problem is not with my Android app).

Here is my code (which I got from How do I send a POST request with PHP?):

$url = 'https://fcm.googleapis.com/fcm/send';
$data = array('score' => '5x1', 'time' => '15:10');

// use key 'http' even if you send the request to https://...
$options = array(
  'http' => array(
    'header'  =>  "Content-type: application/json\r\n" .
                  "Authorization: key=MY_SERVER_KEY\r\n",
    'method'  => 'POST',
    'data' => http_build_query($data),
    'to' => 'MY_FCM'
  )
);
$context  = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if ($result === FALSE) { /* Handle error */ }

var_dump($result);

I feel like I'm doing something terribly basic wrong (like my JSON is not formatted correctly or something).

The firebase apis can be found here: https://firebase.google.com/docs/cloud-messaging/send-message

I've been working on this for a couple days now, and any assistance will be much appreciated. Thanks guys!

Update

A quick note that Heroku doesn't support the HttpRequest() class from what I've experienced, however, cURL works great. Also, I didn't mention it, but I was actually wanting a notification message to be sent, not just a data message. So, my final code looked like the following:

    $curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://fcm.googleapis.com/fcm/send",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\n
    \"notification\" : {\n
    \"body\" : \"Goku\",\n
    \"title\" : \"Over 9000\",\n
    },\n
    \"to\" : \"MY_FCM_TOKEN\"\n
    \"priority\" :
    \"high\"\n
    }",
  CURLOPT_HTTPHEADER => array(
    "authorization: key=MY_SERVER_KEY",
    "cache-control: no-cache",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
Community
  • 1
  • 1

1 Answers1

1

In your code

'http' => array(
    'header'  =>  "Content-type: application/json\r\n" .
              "Authorization: key=MY_SERVER_KEY\r\n",
    'method'  => 'POST',
    'data' => http_build_query($data),
    'to' => 'MY_FCM'
)

you have to send data and to inside the key 'content'.

/* $mydata contains 'data' and 'to' */
'http' => array(
    'header'  =>  "Content-type: application/json\r\n" .
              "Authorization: key=MY_SERVER_KEY\r\n",
    'method'  => 'POST',
    'content' => http_build_query($mydata)
 )

These are few recommended ways to send fcm notification using php

HttpRequest

$request = new HttpRequest();
$request->setUrl('https://fcm.googleapis.com/fcm/send');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'cache-control' => 'no-cache',
  'content-type' => 'application/json',
  'authorization' => 'key=YOUR_FCM_API_KEY'
));

$request->setBody('{
  "data" : {
  "name" : "Goku",
  "power_level" : "Over 9000",
  "fighting_skill" : "excellent"
 },
  "to" : "FCM_ID_OF_RECIEVER"
 }');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}

pecl_http

<?php

$client = new http\Client;
$request = new http\Client\Request;

$body = new http\Message\Body;
$body->append('{
  "data" : {
    "name" : "Goku",
    "power_level" : "Over 9000",
    "fighting_skill" : "excellent"
  },
  "to" : "FCM_ID_OF_RECIEVER"
}');

$request->setRequestUrl('https://fcm.googleapis.com/fcm/send');
$request->setRequestMethod('POST');
$request->setBody($body);

$request->setHeaders(array(
  'cache-control' => 'no-cache',
  'content-type' => 'application/json',
  'authorization' => 'key=YOUR_FCM_API_KEY'
));

$client->enqueue($request)->send();
$response = $client->getResponse();

echo $response->getBody();

cURL

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://fcm.googleapis.com/fcm/send",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\n  \"data\" : {\n    \"name\" : \"Goku\",\n    \"power_level\" : \"Over 9000\",\n    \"fighting_skill\" : \"excellent\"\n  },\n  \"to\" : \"FCM_ID_OF_RECIEVER\"\n}",
  CURLOPT_HTTPHEADER => array(
    "authorization: key=YOUR_FCM_API_KEY",
    "cache-control: no-cache",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
  • I wanted to add that with Heroku, they don't have the packages necessary to use the HttpRequest() class. The cURL example worked fairly well. However, the Firebase service itself seems fairly wonky. Sometimes the notification is received instantly, other times it takes 10 minutes. Furthermore, I didn't realize it, but I actually wanted to send a notification message, not just a data message. So, my final code looked like the following: `code – electr0sheep Dec 20 '16 at 15:44
  • I don't think I can put block code in a comment so I'll modify my original question with my final code. – electr0sheep Dec 20 '16 at 15:50
  • 1
    i have lots of experience with firebase and it works fine you might have to look at your implementation of code. take look at [Firebase Priority](https://firebase.google.com/docs/cloud-messaging/concept-options) – Ashutosh Barthwal Dec 20 '16 at 15:54
  • Once again, it looks like you've hit the nail on the head my friend. I haven't been able to thoroughly test it, but it looks like it's going through instantly all the time now. I'll update my update. – electr0sheep Dec 20 '16 at 16:05