InvalidRegistration error in Firebase Cloud Messaging for Android

49,009

Solution 1

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.

Solution 2

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],

Solution 3

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());
}
Share:
49,009
Wai Yan Hein
Author by

Wai Yan Hein

What up?

Updated on July 09, 2022

Comments

  • Wai Yan Hein
    Wai Yan Hein almost 2 years

    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.

    enter image description here

    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());
        }
    }
    
  • Wai Yan Hein
    Wai Yan Hein over 7 years
    Ah ya. in my database, there is a row with invalid token. I get success return "{\"multicast_id\":8042731220476088762,\"success\":1,\"failu‌​re\":0,\"canonical_i‌​ds\":0,\"results\":[‌​{\"message_id\":\"0:‌​1474456734183863%97d‌​a1d69f9fd7ecd\"}]}". But device does not receive notification.
  • Arpit Patel
    Arpit Patel over 7 years
    on which platform you are not getting notification?
  • Wai Yan Hein
    Wai Yan Hein over 7 years
    On Android. I do not get any notification.
  • Wai Yan Hein
    Wai Yan Hein over 7 years
    I just added the code. That class is declared in the manifest file as well.
  • Wai Yan Hein
    Wai Yan Hein over 7 years
    But I am not doing anything with that class cause I think declare in manifest file is enough. Is it?
  • Wai Yan Hein
    Wai Yan Hein over 7 years
    I was testing on Emulator. When I tested on real device, it is working. Thanks so much.
  • Kamlesh
    Kamlesh over 3 years
    'to' is used to send notification to one user while 'registration_ids' is used to send multiple users. We can count number of $tokens then set 'to' and 'registration_ids' condition according to that. Thanks to ask this question.