Really weird and no one has ever asked this.
I'm getting MismatchSenderIdas an error with my server key as my authorization key(server key).
And on the other hand, I'm getting success as a return result from my push_notification() if my device's token as my authorization key, but no notification is received on my device.
I'm sure that my token is correct because I'm able to send to a single device with token in firebase (single device) console.
Which then leads me to this another question, but then I would like to confirm this issue before moving to the notification part
I'm pretty lost actually, since that all MismatchSenderId errors were resolved with replacing with the correct server key.
<?php
require "dbconfig.php";
$sql = "SELECT token FROM tokendb";
$result = mysql_query($sql) or die($sql."<br/><br/>".mysql_error());
$tokens = array();
while($row = mysql_fetch_assoc($result))
{
echo $row['token']; //this shows the same token compared to the token show in logcat(visual studio)
$tokens[] = $row["token"];
echo '<form id="form1" name="form1" method="post" action="">'.
'<p>From<br>'.
'<input type="text" size="100" maxlength="100" name="From" id="From" /><br>'.
'<p>Title<br>'.
'<input type="text" size="100" maxlength="100" name="Title" id="Title" />'.
'<br>'.
'<input type="submit" name="Send" id="Send" value="Send" />'.
'</form>';
}
$message = array("message" => "notification test");
$message_status = sendFCMMessage($message, $tokens);
echo $message_status;
function sendFCMMessage($message,$target){
//FCM API end-point
$url = 'https://fcm.googleapis.com/fcm/send';
$fields = array();
$fields['body'] = $message;
if(is_array($target)){
$fields['registration_ids'] = $target;
}else{
$fields['to'] = $target;
}
//header with content_type api key
$headers = array(
'Content-Type:application/json',
'Authorization:key=********'
);
//CURL request to route notification to FCM connection server (provided by Google)
$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_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$result = curl_exec($ch);
if ($result === FALSE) {
die('Oops! FCM Send Error: ' . curl_error($ch));
}
curl_close($ch);
return $result;
}
?>
EDIT: This short php code is also giving me MismatchSenderId error
<?php
$ch = curl_init("https://fcm.googleapis.com/fcm/send");
$header=array('Content-Type: application/json',
"Authorization: key=***(serverkey from project)");
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{ \"notification\": { \"title\": \"Test desde curl\", \"text\": \"Otra prueba\" }, \"to\" : \"my device's token\"}");
curl_exec($ch);
curl_close($ch);
?>
UPDATE
Uninstalling and reinstalling the app resolved the issue.
The MismatchSenderId error is encountered when you are attempting to send to a registration token that is associated with a different Sender (Project). From the docs:
A registration token is tied to a certain group of senders. When a client app registers for FCM, it must specify which senders are allowed to send messages. You should use one of those sender IDs when sending messages to the client app. If you switch to a different sender, the existing registration tokens won't work.
Make sure that the Server Key you are using is from the same Sender Project that the registration token is associated to. You can do this by checking your google-services.json file and see if the Sender ID there matches the Sender ID visible in the Firebase Project you are using to send the message.
For the matter of not receiving messages, It's a bit unclear as to what is the structure of payload that your code is sending. Try checking if it is a properly structured message payload with a notification and/or data message payload.
Make your you are taking Server Key from Right place
Now it is little bit tricky to get Server key for Notification from firebase.
Here are the Steps :
GO TO CONSOLE -> YOUR PROJECT -> PROJECT SETTINGS -> CLOUD MESSAGING (Second Tab)
And Take your Server Key and Sender id from their, which will work for you.
Uninstall the App and Re install it and try it.
Related
I researched online and tried various methods to fix this problem however it did not solve the problem. This is the error i get in my php script
{"multicast_id":6412971464416964071,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}
I am using authorisation key which is the server key.
push_notification.php
<?php
function send_notification ($tokens, $message)
{
$url = 'https://fcm.googleapis.com/fcm/send';
$fields = array(
'registration_ids' => $tokens,
'data' => $message
);
$headers = array(
'Authorization:key = ********',
'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_VERIFYHOST, 0);
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;
}
$conn = mysqli_connect("localhost","root","","fcm");
$sql = "Select Token From users";
$result = mysqli_query($conn,$sql);
$tokens = array();
if(mysqli_num_rows($result) > 0 ){
while ($row = mysqli_fetch_assoc($result)) {
$tokens[] = $row["Token"];
}
}
mysqli_close($conn);
$message = array("message" => " FCM PUSH NOTIFICATION TEST MESSAGE");
$message_status = send_notification($tokens, $message);
echo $message_status;
?>
There is a valid token in my database. However it shows invalid registration. How do i fix this?
If it's invalid registration,
check the format of the registration token you pass to the server. Make sure it matches the registration token the client app receives from registering with Firebase Notifications. Do not truncate or add additional characters.
Source: Downstream message error response codes
If that recommended action doesn't work for you, here are additional things that you can do:
Verify ID Tokens. It mentioned about the need to verify the integrity and authenticity of the ID token and retrieve the uid from it.
You may want to also check this suggested solution in this SO post wherein it states that if you retrieve token from db, you make sure the data type for the column is either text or a very long varchar like 200.
I'm trying to setup a server to send push notifications.
I'm trying to send push notification toward user of an specified package e.g. something like com.mysite.android (This options is available in Firebase console).
Checking answers like this I could not understand how to set to parameter to send push notifications to user of an specified package. I can find sample which send notification to specific devices by their ids or news topics.
Clarification: I'm the owner of application which I want sent push notifications.
If it helps here is my code:
<?php
/*
Parameter Example
$data = array('post_id'=>'12345','post_title'=>'A Blog post');
$target = 'single tocken id or topic name';
or
$target = array('token1','token2','...'); // up to 1000 in one request
*/
echo "Start<br/>";
$result = sendMessage('{"id":"hello"}',null);
var_dump($result);
function sendMessage($data,$target){
//FCM api URL
$url = 'https://fcm.googleapis.com/fcm/send';
//api_key available in Firebase Console -> Project Settings -> CLOUD MESSAGING -> Server key
$server_key = 'xxxxxxxxxxxxxxxxxxxkeyxxxxxxxxxxxxxxxxxxxxxxxx';
$fields = array();
$fields['data'] = $data;
$fields['restricted_package_name']='com.mysite.android ';
$fields['dry_run']=true;
if (isset($target)){
if(is_array($target)){
$fields['registration_ids'] = $target;
}else{
$fields['to'] = $target;
}
}
//header with content_type api key
$headers = array(
'Content-Type:application/json',
'Authorization:key='.$server_key
);
$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_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$result = curl_exec($ch);
if ($result === FALSE) {
die('FCM Send Error: ' . curl_error($ch));
}
curl_close($ch);
return $result;
}
?>
Notice: I removed my server_key intentionally.
You cannot send push notifications to any external app except the apps you own, simply the user device token and your server key are linked under one project so you must use a server key and valid device tokens for "X" app
This is manageable. However, for you to be able to send a Notification to an app, you first need to be a valid Sender.
By that, usually (if you are the app owner), all you have to do is Add the App to your Firebase Project, generate the google-services.json file and add it to your Android Project.
If you're not the app owner and you don't want to add the app via your Firebase Project, this can be overridden by simply modifying the google-services.json that is used in the app, adding your SenderID in it. But I highly doubt that you'd be given access to modify an app that isn't yours in the first place.
Note: It is not advisable to modify your google-services.json though.
If you were able to set your peoject as a valid sender, you will have to make use of Topic Messaging and subscribe the devices to a topic name that is their app package name.
Then when sending to the topic, simply use the name of the package in the to parameter like so:
"to": "/topics/<app_package_name_here>"
How can i get Response if the Message was sent or Not, using Php Script, Then i want to use the Response to Determine If the Device is Online or Not,
Here is my Php Script to Send a Message :
function send_push_notification($registration_ids, $message) {
$regId=$registration_ids;
$msg=$message;
$message = array("message" => $msg);
$regArray[]=$registration_ids;
$url = 'https://android.googleapis.com/gcm/send';
$fields = array('registration_ids' => $regArray, 'data' => $message,);
$headers = array( 'Authorization: key=API_KEY','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);
echo $result;
if($result==FALSE)
{
die('Curl Failed');
}
curl_close($ch);
}
Thanks
The response your server gets from GCM server doesn't tell you if the message was sent or not. It only tells you if the message was accepted by the GCM server or rejected. If it's accepted, GCM server will try to deliver it, but there's no guarantee it would succeed. If it's rejected, you get an error message (such as InvalidRegistration, MissingRegistration, etc...).
If you want an acknowledgment of delivery, you must have code in your Android app that upon receiving of the message makes a call to your server, to acknowledge the message was received.
You don't get response from the app; you can only get response from the GCM system itself. When the CURL call completes, $result contains a JSON-encoded object; its id property contains a message ID upon success.
I have created an Android app with Googles' OAuth 2.0 (from developer console) and has an API key for Android application (it use Google Maps, which works by the way).
However, my problem is that I'm using Push Notifications and it works on the android application though (I get the registration ID), but on the server it doesn't work at all.
I'm using PHP and the problem seems to be the API key which is the same as the one I've for the Android application.
So what key am I supposed to use? And how do I retrieve it?
Code:
<?php
function send_push_notification($registatoin_ids, $message) {
// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => $registatoin_ids,
'data' => $message,
);
$headers = array(
'Authorization: key=An_Api_Key',
'Content-Type: application/json'
);
//print_r($headers);
// 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;
}?>
Please check allowed IP addresses in your Google API. You can restrict API access to certain IP addresses and by default one IP address is set when you create new API project.
Remove that IP address so that any IP address (Including your local machine's server) can connect and access the API.
I have implemented similar kind of code and got 401 error. Above fix worked for me. Hope that helps you as well.
I am trying to set up Google Cloud Messaging on Android with PHP (following this tutorial: http://www.androidhive.info/2012/10/android-push-notifications-using-google-cloud-messaging-gcm-php-and-mysql/). My device registers successfully with GCM and then with the server (the regId is stored into the database).
When I try and send to the device nothing is received, although I get this response:
{"multicast_id":4701392840778619841,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1355907831651938%978fee92f9fd7ecd"}]}
Google API reports that no requests have been made.
This is my send_notification function in PHP:
public function send_notification($registration_ids, $message) {
// include config
include_once './config.php';
// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => $registration_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;
}
From research, I have seen similar questions have been asked to this, however they vary slightly - for example, different programming languages and no solution that I have found has solved this problem.
Extra Info:
1. I have checked and cURL is enabled.
2. My onMessage method
protected void onMessage(Context context, Intent intent) {
Log.i(TAG, "Received message");
String message = intent.getExtras().getString("price");
displayMessage(context, message);
// notifies user
generateNotification(context, message);
}
(price in the above just retrieves the message as its stored like this: $message = array("price" => $message); before being given as a parameter to the send_notification function on the server.
I have checked LogCat and 'Received message' does not appear.
Just solved this (although I don't know what was causing the original problem). I shut my device down and started it up again and it went mad receiving all the messages I had sent it over the last few days. Now it receives them as they are sent, so assuming everything else is correct, if anyone is having this problem, try restarting the device.
please generate and use server api key to view for live notification on device.
that is not mention in this post
http://www.androidhive.info/2012/10/android-push-notifications-using-google-cloud-messaging-gcm-php-and-mysql/
I experienced a very similar (same?) problem. My issue was that I changed the String from "price" in the PHP code, but I hadn't done in the Android code. You need to do both. Maybe this will help someone. :)