Invalid JSON payload received when sending request to FCM API - php

I'm sending a request to FCM via my PHP app, but it returns the following error:
{
"code": 400,
"message": "Invalid JSON payload received.
Unknown name \"{\"validateOnly\":true,\"message\":{\"name\":\"testName\",\"token\":\"validToken\"}}\":
Cannot bind query parameter. Field '{\"validateOnly\":true,\"message\":{\"name\":\"testName\",\"token\":\"validToken\"}}'
could not be found in request message.",
"status": "INVALID_ARGUMENT",
"details": [ { "#type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{ "description": "Invalid JSON payload received.
Unknown name \"{\"validateOnly\":true,\"message\":{\"name\":\"testName\",\"token\":\"validToken\"}}\":
Cannot bind query parameter.
Field '{\"validateOnly\":true,\"message\":{\"name\":\"testName\",\"token\":\"validToken\"}}' could not be found in request message."
} ] } ] } }
My notification
$notification = [
'validateOnly' => true,
'message' => [
'name' => $name,
'token' => "validToken"
]
];
$notification = json_encode($notification)
as JSON:
{
"validateOnly":true,
"message":{
"name":"testName",
"token":"validToken"
}
}
My http header
$header = [
'Accept' => 'application/json',
'Content-Length' => strlen($notification),
'Content-Type' => 'application/json',
];
$header = json_encode($header, JSON_UNESCAPED_SLASHES);
as JSON:
{
"Accept":"application/json",
"Content-Length":72,
"Content-Type":"application/json"
}
My cURL code
$curl_session = curl_init();
try {
curl_setopt($curl_session, CURLOPT_URL, $this->_apiUrl);
//_api_Url = https://fcm.googleapis.com/v1/projects/projectName/messages:send?access_token=$access_token
curl_setopt($curl_session, CURLOPT_POST, true);
curl_setopt($curl_session, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl_session, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl_session, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl_session, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_setopt($curl_session, CURLOPT_POSTFIELDS, $notification);
} catch (Exception $e) {
print_r($e);
}
$result = curl_exec($curl_session);
curl_close($curl_session);
My guess is that it's the first two quotes in \"{\"validateOnly\"... that's causing the issue.
Is that possible? If so, how do you suggest I fix it?
Any other ideas? As far as I can tell all my code is correct according to the HTTP v1 docs

Your headers are wrong. This is not how php-curl expects them and because of that your request content type will be the default application/x-www-form-urlencoded instead of seeing it as json. It should look like this:
$header = [
'Accept:application/json',
'Content-Length:'.strlen($notification),
'Content-Type:application/json',
];
curl_setopt($curl_session, CURLOPT_HTTPHEADER, $header);
and don't json encode it, just pass this to curl.
You can find this documented here: https://www.php.net/manual/en/function.curl-setopt.php
An array of HTTP header fields to set, in the format
array('Content-type: text/plain', 'Content-length: 100')

Related

Recaptcha Enterprise API error when creating assessment

I am trying to implement Recaptcha Enterprise, I get the userToken and am attempting to create an assessment but when sending the information get the following response:
{
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name "{JSON SENT}": Cannot bind query parameter. Field '{JSON SENT}' could not be found in request message.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"description": "Invalid JSON payload received. Unknown name \"{JSON SENT}' could not be found in request message."
}
]
}
]
}
}
My php curl file:
<?php
$token = $_GET["token"];
$secret = "SECRET_ID";
$url = "https://recaptchaenterprise.googleapis.com/v1/projects/{project_id}/assessments?key=" . $secret;
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$headers = array(
"Content-Type: application/x-www-form-urlencoded",
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$data = ['event' => ['token' => $token, 'siteKey' => $secret, 'expectedAction' => 'verify']];
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
$resp = curl_exec($curl);
curl_close($curl);
echo ($resp);
My Json
\"{\"event\":
{\"token\":\"TOKEN\",
\"siteKey\":\"SITE_KEY\",
\"expectedAction\":\"verify\"}
}\"
I have tried consulting the enterprise docs but have been unsuccessful. Any and all help would be appreciated.
For the call to googleapis.com you'd have to use an api key, not the site key. Use the site key (your $secret) only where you build the $data array.
You are sending JSON to google, so the Content-Type should be 'application/json; chartype=utf-8'.
In case you are also posting JSON from your website to this php, then you'd need to use
$json=file_get_contents('php://input');
$jdata=json_decode($json);
to retrieve the data, not $_GET[]. Then you could address:
$token=$jdata->token
$action=$jdata->action

perform a curl request with PHP

I am trying to make a call to an API using curl (from the backend of my application directly). It is the first time I use it so I digged around to learn how to do it.
The documentation say that this is the request:
curl --location -g --request POST '{{url}}/api/rest/issues/' \
--header 'Authorization: {{token}}' \
--header 'Content-Type: application/json' \
--data-raw '{
"summary": "This is a test issue",
"description": "This is a test description",
"category": {
"name": "General"
},
"project": {
"name": "project1"
}
}'
This should be the code if I execute it from the terminal (if I get it right). If I want to move execute it in a php script I have to convert this to something like:
<?php
$pars=array(
'nome' => 'pippo',
'cognome' => 'disney',
'email' => 'pippo#paperino.com',
);
//step1
$curlSES=curl_init();
//step2
curl_setopt($curlSES,CURLOPT_URL,"http://www.miosito.it");
curl_setopt($curlSES,CURLOPT_RETURNTRANSFER,true);
curl_setopt($curlSES,CURLOPT_HEADER, false);
curl_setopt($curlSES, CURLOPT_POST, true);
curl_setopt($curlSES, CURLOPT_POSTFIELDS,$pars);
curl_setopt($curlSES, CURLOPT_CONNECTTIMEOUT,10);
curl_setopt($curlSES, CURLOPT_TIMEOUT,30);
//step3
$result=curl_exec($curlSES);
//step4
curl_close($curlSES);
//step5
echo $result;
?>
that I will adapt to my needs. Is this correct? Is there another way to keep it as simple as the documented curl request?
I would use an HTTP client like Guzzle.
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'http://www.miosito.it', [
'form_params' => [
'nome' => 'pippo',
'cognome' => 'disney',
'email' => 'pippo#paperino.com',
]
]);
echo (string) $response->getBody();
There are several ways to do curl. Your code seems okay, you can try out my code too.
$pars=array(
'nome' => 'pippo',
'cognome' => 'disney',
'email' => 'pippo#paperino.com',
);
If sometimes you need to send json encoded parameters then use below line.
// $post_json = json_encode($pars);
Curl code as per below
$apiURL = 'http://www.miosito.it';
$ch = #curl_init();
#curl_setopt($ch, CURLOPT_POST, true);
#curl_setopt($ch, CURLOPT_POSTFIELDS, $pars);
#curl_setopt($ch, CURLOPT_URL, $apiURL);
#curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
#curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = #curl_exec($ch);
$status_code = #curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curl_errors = curl_error($ch);
#curl_close($ch);
echo "<br>Curl Errors: " . $curl_errors;
echo "<br>Status code: " . $status_code;
echo "<br>Response: " . $response;
Please let me know if there you need something else.

Google Mybusiness API getLocatiosn returns empty

I got a verified location in google mybusiness but when i use the API, it returns an empty array [] I am using this endpoint. I am using laravel 6 and curl library for HTTP requests in this project.
'https://mybusiness.googleapis.com/v4/accounts/117177930435384486747/locations'
Here is my whole controller function
public function getLocations(Request $request){
$url = 'https://mybusiness.googleapis.com/v4/accounts/'.$request->account_id.'/locations:batchGet';
$headers = array(
'Content-Type: application/json',
'Authorization: Bearer '.$request->bearer_token
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close ($ch);
return response()->json(json_decode($result,true));
}
What did I miss? I already got the account info by using this endpoint
https://mybusiness.googleapis.com/v4/accounts and it got me a response of
{
"accounts": [
{
"name": "accounts/117177930435384486747",
"accountName": "Michael koh",
"type": "PERSONAL",
"state": {
"status": "UNVERIFIED",
"vettedStatus": "NOT_VETTED"
},
"profilePhotoUrl": "//lh6.googleusercontent.com/-Jv5Xr7SXjuE/AAAAAAAAAAI/AAAAAAAAAAA/QryQ_2-Mjqo/s132-mo/photo.jpg"
}
]
}
In the response, it says not verified. But when i go to google mybusiness UI. I got this when i click manage location. Seems weird because it shows verified.
PS:
I tried getting the location by calling this endpoint GET https://mybusiness.googleapis.com/v4/{parent=accounts/*}/locations but I got an empty array

Google MyBusiness REST API update posts PATCH method request error

I want to update a specific post on google my business. I already got the account_id, location_id, and the post_id. I am using the url https://mybusiness.googleapis.com/v4/{name=accounts/*/locations/*/localPosts/*} and doing PATCH method in my backend. But when I do an update it gets me an
"code": 2,
"field": "update_mask",
"message": "update_mask is required"
I cant understand the update_mask thing in google. Can someone tell me what I should do about this? I am using laravel btw and curl library for http request. Here is my code
public function updatePost(Request $request ){
$url = 'https://mybusiness.googleapis.com/v4/accounts/'.$request->account_id.'/locations/'.$request->location_id.'/localPosts/'.$request->post_id;
$body['languageCode'] = "en-US";
$body['summary'] = $request->summary;
$body['callToAction'] = ['actionType'=> 'Call'];
$body['media'][] = ['mediaFormat'=> 'PHOTO', "sourceUrl" => $request->imageURL];
//Static Token only since for testing
$headers = array(
'Content-Type: application/json',
'Accept: application/json',
'Authorization: Bearer '.'ya29.a0AfH6SMB_1iUG11qj72p-pn_gCkOjUEf-ctvTGnJZ6FNTUy0Q3dYP54TMvI0cr8o0ditLp7CaWOUX5CTWn4v2kyQ-hZKSyuEJu_rBYX7uxvX373I9iVRxoypIZ6xhWDYTr-A_DHcaxGPVs1yz5u-fkYvU-xDppkASNbg'
);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($body));
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($curl);
dd($response);
}
The full message
{
"error": {
"code": 400,
"message": "Request contains an invalid argument.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.mybusiness.v4.ValidationError",
"errorDetails": [
{
"code": 2,
"field": "update_mask",
"message": "update_mask is required"
}
]
}
]
}
}
The docs for patch method
https://developers.google.com/my-business/reference/rest/v4/accounts.locations.localPosts/patch
You need to set query parameters for the upateMask like following.
https://mybusiness.googleapis.com/v4/accounts/2323232334343/locations/232323232/localPosts/23232323232?updateMask=summary
However, I can not edit the other field, for example, title.
Did you find the way of editting the others?
Its clear state that you need to set query parameter 'updatemask' to a field that you want to update. Check this doc for details.

Android Push Notification not sending

I am trying to send push notification using cakephp but push notification are not sent.
Now a days GCM id looks different is google change something in push notification process for eg (fRAvDRuNUU8:APA91bHvSGxi4AVPx2wGTFWb7OyAPPvXoIAcT).
Every time I get a json which is below give:
{
"multicast_id": 5873180458565135923,
"success": 0,
"failure": 1,
"canonical_ids": 0,
"results": [
{
"error": "NotRegistered"
}
]
}
I tried so many code from internet but every time I get the same result.
The code I am using is working on so many other application perfectly.
Below is my code:
` public function sendMessageAndroid($registatoin_ids, $message){
$url = 'https://android.googleapis.com/gcm/send';
$apiKey = "AIzaSyBf5vaONLbMyGdDoOEeC_MTTh9x1G4Qm-4";
$fields = array(
'registration_ids' => $registatoin_ids,//here my gcm id come in //array form array($device_id)
'data' => $message,//this is my message //$send_message['m']=array('msg'=>$message,'type'=>'chat');
);
$headers = array(
'Authorization: key=' . $apiKey,
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
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);
if ($result === FALSE) {
//die('Curl failed: ' . curl_error($ch));
}
curl_close($ch);
return $result;
}`
I tried everything with no luck. Please help.
Yes my problem is solved now.There were no mistake in my code.it was my mobile developers mistake.Whenever you got response like this way below
` {
"multicast_id": 5873180458565135923,
"success": 0,
"failure": 1,
"canonical_ids": 0,
"results": [ { "error": "NotRegistered" }
`
It is defiantly mistake in android code.

Categories