Ii have configured android for FCM.
public class DERFirebaseInstanceIDService extends FirebaseInstanceIdService {
#Override
public void onTokenRefresh() {
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
}
}
The token that I get from firebase server is following
"c5pu6rD06ts:APA91bHEgXUbJR8UegRPnLMgowEC6QxUPP73TiSBIHG1Pe0I8u22298rjpbXBsK94ExTmTbL0VT009AhsIqgMSkoLFZJDuaPSpaLlqBAyIrrtzsdLuWhvCp6CtkZwMT88P-WxBFCT2DH"
This token contains double quotations. So what I am doing wrong that server send me this token. Can any one help me..?
Due to this , when server send request to this token I am getting following error
"message": "The registration token is not a valid FCM registration
token",
"domain": "global",
"reason": "badRequest"
I am developing an Android app that using Push Notification feature. I need to push from server. I use Firebase for it. This is my first time using Firebase. But when I push from server using PHP and CURL, it is giving me invalid registration error.
I get the Firebase token in Android like this
String token = FirebaseInstanceId.getInstance().getToken();
Then I save sent that token to server and saved in the database.
At server, I am pushing like this
class Pusher extends REST_Controller {
function __construct()
{
parent::__construct();
}
public function notification_get()
{
$rows = $this->db->get('device_registration')->result();
$tokens= array();
if(count($rows)>0)
{
foreach($rows as $row)
{
$tokens[] = $row->token;
}
}
$message = array("message"=>"FCM PUSH NOTIFICATION TESTING");
if(count($tokens)>0)
{
$result = $this->send_notification($tokens,$message);
if(!$result)
{
die("Unable to send");
}
else{
$this->response($result, REST_Controller::HTTP_OK);
}
}
}
function send_notification($tokens,$message)
{
$url = 'https://fcm.googleapis.com/fcm/send';
$fields = array(
'registration_ids'=>$tokens,
'data'=>$message
);
$headers = array(
'Authorization:key = AIzaSyApyfgXsNQ3dFTGWR6ns_9pttr694VDe5M',//Server key from firebase
'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)
{
return FALSE;
}
curl_close($ch);
return $result;
}
}
I am using CodeIgniter 3 framework for building Rest API. When I push accessing URL from browser, it returns JSON data with error as in the below screenshot.
As you can see it is giving InvalidRegistration error and message is not pushed to devices. What is wrong with my code?
Additional
This is my FirebaseMessagingService class that show notification in Android
public class FirebaseMessagingService extends com.google.firebase.messaging.FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
showNotification(remoteMessage.getData().get("message"));
}
private void showNotification(String message)
{
Intent i = new Intent(this,MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,i,PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this).setAutoCancel(true)
.setContentTitle("FCM Test")
.setContentText(message)
.setSmallIcon(R.drawable.info)
.setContentIntent(pendingIntent);
NotificationManager manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
manager.notify(0,builder.build());
}
}
Although I am not using codeigniter, I was encountering the InvalidRegistration error while sending to an iOS device, so I thought I would share my solution here.
I had to change registration_ids to to in PHP when sending a Notification message to a single device token, and make sure the value of to was a string and not an array.
Change this:
'registration_ids'=>$tokens,
To this:
'to'=>$tokens[0],
Invalid Registration ID Check the formatting of the registration ID
that you pass to the server. Make sure it matches the registration ID
the phone receives in the com.google.firebase.INSTANCE_ID_EVENT
intent and that you're not truncating it or adding additional
characters. Happens when error code is InvalidRegistration.
Please check with both the side app side and your side that the exact same registration id is stored in the server which Application on mobile receives it in on onTokenRefresh method. You should have received the exact same registration token as developer got in FirebaseInstanceId.getInstance().getToken()
As i got your comment and you've updated the code here is some change in your code it is from google doc it self...
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// TODO(developer): Handle FCM messages here.
Log.d(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated. See sendNotification method below.
}
Firebase has three message types:
Notification messages: Notification message works on background or
foreground. When app is in background, Notification messages are
delivered to the system tray. If the app is in the foreground,
messages are handled by onMessageReceived() or
didReceiveRemoteNotification callbacks. These are essentially what is
referred to as Display messages.
Data messages: On Android platform, data message can work on
background and foreground. The data message will be handled by
onMessageReceived(). A platform specific note here would be: On
Android, the data payload can be retrieved in the Intent used to
launch your activity.
Messages with both notification and data payloads: When in the
background, apps receive the notification payload in the notification
tray, and only handle the data payload when the user taps on the
notification. When in the foreground, your app receives a message
object with both payloads available. Secondly, the click_action
parameter is often used in notification payload and not in data
payload. If used inside data payload, this parameter would be treated
as custom key-value pair and therefore you would need to implement
custom logic for it to work as intended.
For Java in Android Do not use FirebaseInstallation
for generating token i don't know why but it does not return the valid token. every time I receive "InvalidRegistration" when try to POST through FCM REST API.
{
"multicast_id": 8303815118005358735,
"success": 0,
"failure": 1,
"canonical_ids": 0,
"results": [
{
"error": "InvalidRegistration"
}
]
}
Instead Use This:
if (firebaseUser != null) {
FirebaseInstanceId.getInstance().getInstanceId()
.addOnCompleteListener(task -> {
if (!task.isSuccessful()) {
Log.d(TAG, "getInstanceId failed", task.getException());
return;
}
if (task.getResult() != null) updateToken(task.getResult().getToken());
});
}
private void updateToken(String refreshToken) {
DocumentReference documentReference;
Token token1 = new Token(refreshToken);//just a class with str field
Map<String, Object> tokenMAp = new HashMap<>();
tokenMAp.put("tokenKey", token1.getToken());
Log.d(TAG, "updateToken: " + token1.getToken());
String id = firebaseUser.getUid();
baseref=sp.getString(BASE_REF,DEFAULT);
documentReference= FirebaseFirestore.getInstance().document(baseref);
updateDocWithToken(documentReference,tokenMAp);
}
private void updateDocWithToken(DocumentReference documentReference, Map<String, Object> tokenMAp) {
documentReference.set(tokenMAp, SetOptions.merge());
}
Using Xamarin and AWS SNS trying to get push notifications working. They were working just fine the other day. Today they aren't.
I have an Android device and an iOS device. Whenever I change anything in my application the other device is supposed to get a push notification. The iOS device is working.
C# code for subscribing on Android:
[Service(Exported = false)]
public class RegistrationIntentService : IntentService
{
static object locker = new object();
public RegistrationIntentService() : base("RegistrationIntentService") { }
protected override void OnHandleIntent(Intent intent)
{
try
{
Log.Info("RegistrationIntentService", "Calling InstanceID.GetToken");
lock (locker)
{
var instanceID = InstanceID.GetInstance(this);
var token = instanceID.GetToken(
"shhh it's a secret.", GoogleCloudMessaging.InstanceIdScope, null);
Log.Info("RegistrationIntentService", "GCM Registration Token: " + token);
SendRegistrationToAppServer(token);
Subscribe(token);
}
}
catch (Exception e)
{
Log.Debug("RegistrationIntentService", "Failed to get a registration token");
return;
}
}
void SendRegistrationToAppServer(string token)
{
// Add custom implementation here as needed.
//... handling my token on the back-end
}
void Subscribe(string token)
{
var pubSub = GcmPubSub.GetInstance(this);
pubSub.Subscribe(token, "/topics/global", null);
}
}
Dropping some breakpoints in there I can see that my device token does match the token for the AWS endpoint that I'm trying to send messages to. For some reason though, I keep getting error messages back from AWS. This is what AWS is sending me:
{"DeliveryAttempts":1,"EndpointArn":"arn:aws:sns:...:endpoint/GCM/...","EventType":"DeliveryFailure","FailureMessage":"Platform token associated with the endpoint is not valid","FailureType":"InvalidPlatformToken","MessageId":"...","Resource":"arn:aws:sns:...:app/GCM/...","Service":"SNS","Time":"2016-03-28T18:22:59.360Z"}
What could be causing this if I know the token I'm getting back from the application matches the token of my AWS endpoint?
It is most likely that the registration id that is being passed to the SNS is not correct. I would recommend that you turn on the delivery status and see the actual response from GCM, see https://mobile.awsblog.com/post/TxHTXGC8711JNF/Using-the-Delivery-Status-feature-of-Amazon-SNS for information
Brief : In parse installation table device token is not added properly when I use new GCM API.
right now following type of device token added into Parse installation table.
DeviceToken : |ID|1|:crGctxOB068:APA91bFgPRehabJcm9CYdS948iqX2_ppLj02CtbzmEHR0cfbuPooq5F--hqqvR9AH-Ez6MWMQON1Toc2DiNJTNdpRc3nmm3ukIpWJ1jHaXq0Iug6MoHbmKb9U0ak2CrKznkpKnPY5_Jp
Detailed description :
I have used new GCM api to get registration id.
I need that regId for internal use.
I have used code from following link of google: Google cloud messaging android.
I have noted one point. when ever I start app parse get deviceToken properly. After login I am updating "user" field using following code in onCreate of mainActivity
ParseACL acl = new ParseACL();
acl.setPublicReadAccess(true);
acl.setPublicWriteAccess(true);
ParseInstallation installation = ParseInstallation.getCurrentInstallation();
installation.setACL(acl);
if (ParseUser.getCurrentUser() != null) {
installation.put("user", ParseUser.getCurrentUser());
}
installation.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.e("installation", "success");
Log.i("parse", "token after save : " + ParseInstallation.getCurrentInstallation().getString("deviceToken"));
ParsePush.subscribeInBackground("", new SaveCallback() {
#Override
public void done(ParseException e) {
if (e != null) {
Log.e("error: ", e.getLocalizedMessage());
e.printStackTrace();
} else {
Log.e("subscribed: ", "to broadcast channel");
Log.i("parse", "token after subscribe : " + ParseInstallation.getCurrentInstallation().getString("deviceToken"));
}
}
});
} else {
Log.e("installation", "failed");
e.printStackTrace();
}
}
});
Generally when above code run deviceToken got changed to Above mentioned token which seems wrong. So My push notification is not working.
I have solved issue.
I need to pass GCM device token to other webservice so I have used following code to get token from GCM.
InstanceID instanceID = InstanceID.getInstance(getApplicationContext());
String token = instanceID.getToken(CommonUtils.SENDER_ID,
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
After getting token from this code parse's deviceToken changed.
So instead of using above code I have used following code to get deviceToken and it solved the issue.
ParseInstallation.getCurrentInstallation().getString("deviceToken");
I'm using Amazon SNS to send push notifications to an Android device. If I send the following JSON I can't read the parameters in the data element.
{
"default": "message here",
"GCM": {
"data": {
"message": "This is the message"
}
}
}
I can read the default element but in my broadcastreceiver I can't do this.
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
Log.d("GCM",extras.getString("message");
}
Trying to read the message element causes an error.
If I send directly through GCM I can read all of the parameters that start with data. using the above method with no problem at all.
What am I doing wrong?
You need escape double quotation in GCM value.
{ "default": "message here", "GCM": "{ \"data\": { \"message\": \"This is the message\" } }" }