MissingRegistraton error when trying to send data to GCM - php

I've searched a lot but couldn't find any solution for this question.
I'm using a PHP server and is trying to send PushNotifications to my Android app. But when I'm trying out my code in the browser I get this error: "Error=MissingRegistration".
Here is the code that I run:
registration_ids = array($regId);
$message = array(
'hangMessage' => $message,
'userId' => $user_id
);
$result = $gcm->send_notification($registration_ids, $message);
And this is the code that I call:
$url = "https://android.googleapis.com/gcm/send";
$fields = array(
'registration_ids' => $regisration_ids,
'data' => $message,
);
$headers = array(
'Authorization: key=' . GOOGLE_API_KEY,
'Content-Type= application/json',
);
//Open connection
$ch = curl_init();
//Set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//Disabling SSL Certificate support temporarly
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
//Execute psot
$result = curl_exec($ch);
if($result == false){
die('Curl failed: ' . Curl_error($ch));
}
//Close connection
curl_close($ch);
echo $result;
The Request doesn't even come all the way to the server according to the Google APIs Console Report system.
Anyone have any idea what could be wrong?

Your request should look like this :
Content-Type:application/json
Authorization:key=AIzaSyB-1uEai2WiUapxCs2Q0GZYzPu7Udno5aA
{
"registration_ids" : ["APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx..."],
"data" : {
...
},
}
Therefore I believe the error might be in this line :
'Content-Type= application/json'
Try to change the = to :.
Since the content type header is invalid, the GCM server may assume a default value for the content type (which might be application/x-www-form-urlencoded;charset=UTF-8, in which case the Registration ID requires a different key, which would explain the MissingRegistration error).
BTW, the fact that you get a MissingRegistraton error means that the request does reach the GCM server. GCM requests are not logged in the Google APIs Console Report system.

Related

Firebase Cloud Message (FCM) : trying to send message to device from PHP (error: InvalidRegistration)

I'm trying to send push messages from PHP but I'm getting the following error message:
{"multicast_id":4832091122368281316,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}
I suppose there is a mismatch with the browser ID but I don't know which one I'm supposed to use.
When I register the push notification through JS, I receive the following payload on my PHP server:
{"endpoint":"https://fcm.googleapis.com/fcm/send/XXX:YYY","expirationTime":null,"keys":{"p256dh":"ZZZ","auth":"AAA"}}
To send the message in PHP, I have used the following code (found on stackexchange):
function sendnotification($to, $title, $message, $img = "", $datapayload = "")
{
$msg = urlencode($message);
$data = array(
'title'=>$title,
'sound' => "default",
'msg'=>$msg,
'data'=>$datapayload,
'body'=>$message,
'color' => "#79bc64"
);
if($img)
{
$data["image"] = $img;
$data["style"] = "picture";
$data["picture"] = $img;
}
$fields = array(
'to'=>$to,
'notification'=>$data,
'data'=>$datapayload,
"priority" => "high",
);
$headers = array(
'Authorization: key=MYSERVERKEY',
'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 );
return $result;
I think I'm using the right server key, when I don't, I get a different error message.
For $to, I'm wondering what I should use. I thought I had to use XXX:YYY after the endpoint but it's not working (XXX is very short, YYY is very long). I have also tried ZZZ and AAA but it doesn't help either.
My questions:
What kind of ID should I be using to send the message to one specific browser ?
What should I do to send a notification to all registered browser?
Thanks!
Well you have to make sure store the token of your user browser, which you can only get when they allow on request prompt e.g.
On user Allow the request it generate the token which look like as below
This token you can use for send the message to specific browser.
So in your code where as your $to = it should be the device token.
i.e. "to": "<DEVICE_REGISTRATION_TOKEN>"

cURL_init() stops the program from running

I have added the .php files on my server to send the notifications using FCM, but the code stops running when I create the actual message. I have a constructor for push and when I call it in sendSinglePush, it does not do anything.
The rest is working properly. I get the parameters ok, and the devicetoken. I just need to create that push and it should work. I've used the same sendSinglePush.php for testing on localhost, and it works. When I add it on server it just stops.
EDIT: As per #ADyson, who helped me understand abit about logging my errors, I started to log every variable from the start to the point where it crashes. The $push it's alright, the problem it's on Firebase.php:
<?php
class Firebase {
public function send($registration_ids, $message) {
$fields = array(
'registration_ids' => array($registration_ids),
'data' => $message,
);
//print_r($fields);
return $this->sendPushNotification($fields);
}
/*
* This function will make the actuall curl request to firebase server
* and then the message is sent
*/
private function sendPushNotification($fields) {
//importing the constant files
require_once 'Config.php';
//firebase server url to send the curl request
$url = 'https://fcm.googleapis.com/fcm/send';
//building headers for the request
$headers = array(
'Authorization: key=' . FIREBASE_API_KEY,
'Content-Type: application/json'
);
//Initializing curl to open a connection
$ch = curl_init();
print_r(curl_error($ch));
//Setting the curl url
curl_setopt($ch, CURLOPT_URL, $url);
//setting the method as post
curl_setopt($ch, CURLOPT_POST, true);
//adding headers
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//disabling ssl support
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
//adding the fields in json format
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
//finally executing the curl request
$result = curl_exec($ch);
print_r($result);
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
print_r(curl_error($ch));
}
//Now close the connection
curl_close($ch);
//and return the result
return $result;
}
}
And the methods are called from sendSinglePush.php, where all the variables are sent correctly:
$mPushNotification = $push->getPush();
//print_r($mPushNotification);
//getting the token from database object
$devicetoken = $db->getTokenByEmail($_POST['email']);
//print_r($devicetoken);
//creating firebase class object
$firebase = new Firebase();
//sending push notification and displaying result
$firebase->send($devicetoken, $mPushNotification);
I have added different print_r() to check the output using POSTMAN and, from that code, the $headers are fine, after the $ch = curl_init(); nothing else shows up. I tried to add print_r(curl_error($ch)); but it does not show enything. Also, I tried with print_r(1); under the $ch = curl_init();to see if the code keeps running, but on postman there was no answer, only a blank screen and 500 Internal Server Error.

Can i store static API Key in php file safely

i want to use FCM in my android application , and i was wondering what is the best practice to store a static API such as Server Key API of FCM .
And after a lot o reading i found that even using ProGard doesn't save the API securely, so the conclusion is to never store keys in the app source code .
My solution is to save the key in a .php file like this, so that every time a device send a notification it sends data ( Notification title , message .. ) to my server that contain the server key and redirect the request to https://fcm.googleapis.com/fcm/send
My php file :
<?php
require_once __DIR__ . '/notification.php';
$notification = new Notification();
$title = "Notification Title";
$message = "Notification Message";
$notification->setTitle($title);
$notification->setMessage($message);
$firebase_api = "API_STATIC_SERVER_CODE_THAT_I_NEED_TO_HIDE";
$requestData = $notification->getNotificatin();
$fields = array(
'to' => '/topics/Test_Topic',
'data' => $requestData,
);
$url = 'https://fcm.googleapis.com/fcm/send';
$headers = array(
'Authorization: key=' . $firebase_api,
'Content-Type: application/json'
);
// Open connection
$ch = curl_init();
// Set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Disabling SSL Certificate support temporarily
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
// Execute post
$result = curl_exec($ch);
if($result === FALSE){
die('Curl failed: ' . curl_error($ch));
}
// Close connection
curl_close($ch);
echo '<h2>Result</h2><hr/><h3>Request </h3><p><pre>';
echo json_encode($fields,JSON_PRETTY_PRINT);
echo '</pre></p><h3>Response </h3><p><pre>';
echo $result;
echo '</pre></p>';
?>
But, is that safe ? Could hackers some how download my php content ( without hacking my server ) , or the fact that i am using HTTPS connections keeps my data safe .
And what else can i do if it's not safe enough
Thank you

How to set up the New Google Cloud Messaging API server implementation and Hosting using PHP?

I am using the new Google Cloud messaging functionality and it's developed successfully in client side and receiving push notification without any dropping. But I'm using an old Send function on the server. Now I want to implement new send function (XMPP) using PHP.
I have registered here also https://services.google.com/fb/forms/gcm/ and got the response mail and key from the google.
And from that I got that I have to implement the SmackCcsClient Java class and two libraries. But I have no idea how to host that file to my PHP server.
After some research I got the function for PHP and xmphp libraries for PHP
$conn = new XMPPHP_XMPP($host, $port, $user, $password, $resource,
$server, $printlog, $loglevel);
But can't get the success it's saying could not connect.
You can use this class:
class gcm {
public static function send_notification($deviceid, $message) {
// include config
// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => (is_array($deviceid) ? $deviceid : array($deviceid)),
'data' => array("message" =>$message),
);
$headers = array(
'Authorization: key=YOUR-AUTH-KEY',
'Content-Type: application/json'
);
// Open connection
$ch = curl_init();
// Set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Disabling SSL Certificate support temporarly
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
// Execute post
$result = curl_exec($ch);
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
// Close connection
curl_close($ch);
}
}

GCM denying the access

I'm working on GCM to send messages to android devices. It worked perfectly with in localhost. But when I tried with the remote server, GCM not allowing the to access it. It shows as "Failed to connect to : Permission denied". I thought, it is the problem with using the same api key for both localhost and remote server. I also changed the api key. Can anyone explain me whats the problem with this. Thanks. The GCM code goes like this.
<?php
class GCM {
//put your code here
// constructor
function __construct() {
}
/**
* Sending Push Notification
*/
public function send_notification($registatoin_ids, $message) {
// include config
include_once './config.php';
// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => $registatoin_ids,
'data' => $message,
);
$headers = array(
'Authorization: key=' . GOOGLE_API_KEY,
'Content-Type: application/json'
);
// Open connection
$ch = curl_init();
// Set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Disabling SSL Certificate support temporarly
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
// Execute post
$result = curl_exec($ch);
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
// Close connection
curl_close($ch);
echo $result;
}
}
?>
Clear all the IP Address from Server Key Page of Google Console, maybe this will solve your problem. If not please contact in comments.

Categories