HTTPClient can't make POST request to FCM
veso266 opened this issue · 4 comments
Questions should go to https://forum.phalconphp.com
Documentation issues should go to https://github.com/phalcon/docs/issues
Expected and Actual Behavior
Send POST request in this format to https://fcm.googleapis.com/fcm/send/
POST / HTTP/1.1
Host: 172.16.101.13:8888
Accept: /
Authorization: key=API_KEY_HERE
Content-Type: application/json
Content-Length: 410
{"registration_ids":["epj2qIlkiUw:APA91bG3v55hJPDLwEJz67pgAAqdQZAP96x16Rk-Smijdc-Kjn1ltLrwuCqrbF4ULcrsfqs7EmTj3c2USWvuaIinUkgEJpg1qq-_bdyhiswXhhzkd-zTUfah_AgMRoynDu6pTN0kUupR"],"data":{"message":"To je test","title":"Test","subtitle":"Testing je \u010dudna stvar","tickerText":"Text gre sem...Text gre sem...Text gre sem...Text gre sem","vibrate":1,"sound":1,"largeIcon":"large_icon","smallIcon":"small_icon"}}
Instead request is sent like this
POST / HTTP/1.1
Host: 172.16.101.13:8888
User-Agent: Phalcon HTTP/0.0.2 (Curl)
Accept: */*
Authorization: key=API_KEY_HERE
Content-Type: application/json
Content-Length: 410
{"registration_ids":["epj2qIlkiUw:APA91bG3v55hJPDLwEJz67pgAAqdQZAP96x16Rk-Smijdc-Kjn1ltLrwuCqrbF4ULcrsfqs7EmTj3c2USWvuaIinUkgEJpg1qq-_bdyhiswXhhzkd-zTUfah_AgMRoynDu6pTN0kUupR"],"data":{"message":"To je test","title":"Test","subtitle":"Testing je \u010dudna stvar","tickerText":"Text gre sem...Text gre sem...Text gre sem...Text gre sem","vibrate":1,"sound":1,"largeIcon":"large_icon","smallIcon":"small_icon"}}
I am sending POST request with CURL like this fine:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
// API access key from Google API's Console
define( 'API_ACCESS_KEY', 'AIzaSyCwfJLBQBXPVOm7gae96VVEJMm5tlZDo48' );
@$DeviceToken = $_GET['id'];
if (!isset($DeviceToken))
{
$DeviceToken = "epj2qIlkiUw:APA91bG3v55hJPDLwEJz67pgAAqdQZAP96x16Rk-Smijdc-Kjn1ltLrwuCqrbF4ULcrsfqs7EmTj3c2USWvuaIinUkgEJpg1qq-_bdyhiswXhhzkd-zTUfah_AgMRoynDu6pTN0kUupR";
$registrationIds = array( $DeviceToken );
}
$registrationIds = array( $DeviceToken );
// prep the bundle
$msg = array
(
'message' => 'To je test',
'title' => 'Test',
'subtitle' => 'Testing je čudna stvar',
'tickerText' => 'Text gre sem...Text gre sem...Text gre sem...Text gre sem',
'vibrate' => 1,
'sound' => 1,
'largeIcon' => 'large_icon',
'smallIcon' => 'small_icon'
);
$fields = array
(
'registration_ids' => $registrationIds,
'data' => $msg
);
$headers = array
(
'Authorization: key=' . API_ACCESS_KEY,
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt( $ch,CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send' );
curl_setopt( $ch,CURLOPT_POST, true );
curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );
$result = curl_exec($ch );
curl_close( $ch );
echo $result;
while using HTTPClient like this:
// get available provider Curl or Stream
$provider = Request::getProvider();
$provider->setBaseUri('https://fcm.googleapis.com/fcm/send/'); // <--- FCM URL
$DeviceToken = "epj2qIlkiUw:APA91bG3v55hJPDLwEJz67pgAAqdQZAP96x16Rk-Smijdc-Kjn1ltLrwuCqrbF4ULcrsfqs7EmTj3c2USWvuaIinUkgEJpg1qq-_bdyhiswXhhzkd-zTUfah_AgMRoynDu6pTN0kUupR";
$registrationIds = array( $DeviceToken );
// prep the bundle
$msg = array
(
'message' => 'To je test',
'title' => 'Test',
'subtitle' => 'Testing je čudna stvar',
'tickerText' => 'Text gre sem...Text gre sem...Text gre sem...Text gre sem',
'vibrate' => 1,
'sound' => 1,
'largeIcon' => 'large_icon',
'smallIcon' => 'small_icon'
);
$fields = array
(
'registration_ids' => $registrationIds,
'data' => $msg
);
$provider->header->set('Authorization', 'key=' . API_ACCESS_KEY);
$provider->header->set('Content-Type', 'application/json');
$response = $provider->post('', json_encode( $fields ));
I don't know why Curl version works fine while Incubator (which wraps Curl) does not
Google complains only with Something went wrong 404 Error
Details
- Phalcon Framework version: (3.4.3)
- Phalcon Incubator version: (latest branch, github (no composer))
- PHP Version: 7.2.18
- Operating System: Docker Ubuntu
- Server: Apache
Hopefully you can figure out why it doesn't work as I would realy like to use incubator instead of curl as its neeter
Thanks for Anwsering and Best Regards
Why do you post token? I hope they are not valid or sensitive.
The url https://fcm.googleapis.com/fcm/send/
does not exist: 404
EDIT: just found this: https://firebase.google.com/docs/cloud-messaging/http-server-ref
So seems like this enpoint exists.
So forget above.
Its the slash at the end of the url.
Change
https://fcm.googleapis.com/fcm/send/
to
https://fcm.googleapis.com/fcm/send
and it works.
This is no bug at phalcon incubator as far i can see.
Try open https://fcm.googleapis.com/fcm/send/
=== 404
Try open https://fcm.googleapis.com/fcm/send
=== redirect to https://firebase.google.com/docs/cloud-messaging/http-server-ref
EDIT2: BTW
You should use setBaseUri()
to set the - well - base uri
and use the path at post()
.
Like:
$provider->setBaseUri('https://fcm.googleapis.com');
....
$response = $provider->post('fcm/send', json_encode( $fields ));
oh right a / at the end and everything fails 😄
BTW: How can I not send User-Agent header? is there any option for that without modifying the class?
as for baseUrl I didn't know why there are 2 arguments for post() 😄
BTW: is there any diference between Accept: / and Accept: / ?
How can I not send User-Agent header?
You can set options.
Have a look at
::getProvider()
returns \Phalcon\Http\Client\Provider\Curl
and Curl
has an ::initOptions()
method. There you can see the default options that will be set.
If you want to change something you can use ::setOption()
or ::setOptions()
.
Example:
$provider->setOption(CURLOPT_USERAGENT, null);
or this
$provider->setOption('curlopt_useragent', null);
If you use a config then i recommend the string version like
$config = [
'...' => [
// CURLOPT_USERAGENT => null,
// becomes
// 10018 => null,
// and could cause trouble
// so better use the name "CURLOPT_USERAGENT" or "curlopt_useragent"
'curlopt_useragent' => null,
],
];
I didn't know why there are 2 arguments for post()
This is just in case you do not set the base uri. Actually you can do what ever you want.
You could set the base url example.com
and call
::post('foo/bar/', $params)
POST example.com/foo/bar
and later
::get('foo/bar')
GET example.com/foo/bar
and later
::head('baz')
example.com/baz
is there any diference between Accept: / and Accept: / ?
This is the same. I guess the *
ect did not went through the editor ? ...
If you asking for Accept: */*
then have a look at https://stackoverflow.com/a/14772709/3411766
accept: */* simply means that any data of whatever mimetype is accepted
Thank you for helping and have a nice day 😃