62

I am new to firebase I am learning it like a toddler learning to walk. So far I have managed to send a message to my own phone using a token generated for my phone by firebase framework. Now here's where it gets tricky (in my opinion). There is a method called onTokenRefresh() in the FirebaseInstanceIdService extended service. Since it is called refresh, Then I am assuming that it will change. I want to know when this token is created and when will it be changed?

And if it changes, suppose I send a message to a device with token 'A' which is offline for now, so it will be queued. Now when the device gets online, it will "refresh" the token to 'B'. Now as the message was supposed to be delivered to token 'A', the message will never be delivered. How can I manage this situation?

yaxe
  • 367
  • 5
  • 26
roostaamir
  • 1,928
  • 5
  • 24
  • 51

3 Answers3

72

The token is generated, after the app is first launched, as soon as the phone can connect to the Google servers. Due to the required connectivity this might not happen immediately, but in most of the cases it will happen in few seconds after the user open the app. As soon as the token is generated the method onTokenRefresh() is called.

As you pointed out the token can change, in which case the onTokenRefresh() method will be called again.
The refresh event is somehow rare, don't expect to see it often at all.

When the refresh token happens, all the messages that have been "successfully" sent (the API returned you a message-id) to the old token will be delivered.

Finally, even after the refresh happened the old token will still be working for a short period, to allow the app to communicate the new token to its back-end.

Diego Giorgini
  • 12,489
  • 1
  • 47
  • 50
  • 13
    I want to store FCM token in my android app user's table in database when user register to the app . When i want to send notification to specific user then i will fetch Token from corresponding row and send push notification.But i am confused that whenever app user logout from his app and register new account from same device ,then there will be two row and hence two Token for same device on database. How to handle such case? What happen to old Token in device? please anyone can help me?? – Roshan Sharma Jun 08 '16 at 06:09
  • the short answer is that you need some logic to handle this situation, and probably you need to design your database to support such logic in an efficient way. Sorry if I don't go into details but the full answer would be really long here. – Diego Giorgini Jun 08 '16 at 06:21
  • 2
    @DiegoGiorgini Could you add these details in the FCM doc please? – Louis CAD Nov 04 '16 at 12:05
  • 2
    can someone tell me what are the reasons when token will refresh? Is there a default time after which the token will refresh for sure? – user734028 Nov 07 '16 at 12:52
  • 2
    @RoshanSharma You should send firebase token to server with device id. Before adding new token to row, find device id if it is exist then delete. than insert it – Samar Haider Apr 27 '17 at 06:25
  • Great answer, Diego. I have the same question as @Roshan and posted it here: https://stackoverflow.com/questions/47217462/how-to-handle-firebase-cloud-messaging-ontokenrefresh-on-the-back-end If you have any insight on this it will be much appreciated. – Jannie Theunissen Nov 10 '17 at 07:14
  • 1
    @RoshanSharma you can call FirebaseInstanceId.deleteInstanceId() in your app, then Resets Instance ID , revokes all tokens and generate new token. – sandeepmaaram Jul 31 '19 at 12:43
31

On initial startup of your app, the sdk of FCM generates the registration token for the client app instance. As above said, It is a rare event. To be specific,The registration token may change when:

  • The app deletes Instance ID.
  • The app is restored on a new device
  • The user uninstall/reinstall the app
  • The user clears app data.

Instance ID provides a unique ID per instance of your apps.Instance ID provides a simple API to generate security tokens that authorize third parties to access your app's server side managed resources.The Instance ID server can even tell you when the device on which your app is installed was last used.We can use this to decide whether to keep data from the app or send a push message to re-engage with the users.

Every time the device token is changed, It is reflected in onTokenRefresh() method.For getting the device token when it is changed, we can call this method to get the refreshed token.

and to get the device token at any time we can use FirebaseInstanceId.getInstance().getToken() method to get the current device token.It takes a bit of time to get the device token.

Click here to read more about accessing device registration token.

Prakhar Anand
  • 311
  • 3
  • 4
4
  • onTokenRefresh() and FirebaseInstanceIdService are deprecated.
  • This call is also deprecated FirebaseInstanceId.getInstance().getToken()

Instead, You should override onNewToken(String token) in FirebaseMessagingService. This method triggered when the token is changed. Once you override this method, you can safely remove FirebaseInstanceIdService whcih contains onTokenRefresh().

When token can change?

  • App deletes Instance ID
  • App is restored on a new device
  • User uninstalls/reinstall the app
  • User clears app data

How to retrieve the current token:

by calling FirebaseInstanceId.getInstance().getInstanceId():

FirebaseInstanceId.getInstance().getInstanceId()
    .addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
        @Override
        public void onComplete(@NonNull Task<InstanceIdResult> task) {
            if (!task.isSuccessful()) {
                Log.w(TAG, "getInstanceId failed", task.getException());
                return;
            }

            // Get new Instance ID token
            String token = task.getResult().getToken();

            // Log and toast
            String msg = getString(R.string.msg_token_fmt, token);
            Log.d(TAG, msg);
            Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
        }
    });

For more info: https://firebase.google.com/docs/cloud-messaging/android/client

For Managing tokens for specific sender id (other than the default sender id), check here

Islam Assi
  • 991
  • 1
  • 13
  • 18