InvalidRegistration error in Firebase Cloud Messaging for Android

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.


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

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());
}