91

I would like to know what would be the correct way to get Firebase token for sending push notification now that getToken() is deprecated.

noogui
  • 15,376
  • 3
  • 18
  • 42
Bhaskar Jyoti Dutta
  • 1,118
  • 1
  • 7
  • 19

2 Answers2

160

UPDATED ANSWER

FirebaseInstanceId is deprecated but now you can use FirebaseInstallations.getInstance().getToken() or FirebaseMessaging.getInstance().token.

For example:

FirebaseInstallations.getInstance().getToken(true).addOnCompleteListener {
        fbToken = it.result!!.token
        // DO your thing with your firebase token
}

Or another option:

FirebaseMessaging.getInstance().token.addOnCompleteListener {
        if(it.isComplete){
            fbToken = it.result.toString()
            // DO your thing with your firebase token
        }
}

OLD ANSWER

As documentation says :

This method was deprecated. In favour of getInstanceId().

getInstanceId() will return a Task with and InstanceIdResult. Like this:

 FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener( new OnSuccessListener<InstanceIdResult>() {                    
                @Override
                public void onSuccess(InstanceIdResult instanceIdResult) {
                      String deviceToken = instanceIdResult.getToken();
                      // Do whatever you want with your token now
                      // i.e. store it on SharedPreferences or DB
                      // or directly send it to server 
                }
});

Though is true that this approach will literally replace the use of FirebaseInstanceId.getInstanceId().getToken(), it does not solve the fact that FirebaseInstanceIdService is also deprecated leaving us with another question that is: where to use it? It can be used in any Activity context that it will always return the token. But what if we want to get the token only on creation and when it is rarely updated? For that you should override new method onNewToken from our old FirebaseMessagingService implementation: (Yes, "Messaging", not "InstanceId")

@Override
public void onNewToken(String s) {
    super.onNewToken(s);
    String deviceToken = s;
    // Do whatever you want with your token now
    // i.e. store it on SharedPreferences or DB
    // or directly send it to server 
}

This way code will remain leaner and wont even be necessary to use the first approach.

Facundo Larrosa
  • 2,561
  • 2
  • 9
  • 19
  • I am using this in fragment and it is showing -Non-static method 'getInstanceId()' cannot be referenced from a static contex -How to solve it – Bhaskar Jyoti Dutta Jul 01 '18 at 17:20
  • Sorry, my mistake. I've edited the answer to call getInstance also as getInstanceId is an instance method. – Facundo Larrosa Jul 01 '18 at 17:22
  • @jantoo did you tried the edited answer? – Facundo Larrosa Jul 01 '18 at 17:27
  • @BhaskarJyotiDutta You did it!. Also please approve the edit I've suggested to use the correct way and grammar to ask in Stack Overflow – Facundo Larrosa Jul 01 '18 at 17:38
  • 1
    Sorry, I did not understand. I am I not good at English? (Sorry, if I have done some mistake) – Bhaskar Jyoti Dutta Jul 01 '18 at 17:46
  • The onSuccess callback enter only once, the first time. If you want to get the Token that the app have already registered in a second time? I try to find out a way to require it without storing in app preferences – phemt.latd Jul 03 '18 at 08:56
  • @phemt.latd I did not understand your question. – Facundo Larrosa Jul 03 '18 at 12:56
  • @Facundo sorry, if you use the new async listener to get the token, the first time the application get it, the next time the app not fire the callback beacuse the token is already generated. There is a method to get the already generated token or you must save it in SharedPreferences when the success callback is fired? – phemt.latd Jul 06 '18 at 14:01
  • @phemt.latd this code always returns the token, not only the first time. It will be executed only when token is updated if you put this code inside method onTokenRefresh. if you want to retrieve the token every time the app starts you can include this code on your MainActivity.onCreate method. – Facundo Larrosa Jul 06 '18 at 14:52
  • Why passing `context` when actually it can be done without?!! – Hamzeh Soboh Jul 12 '18 at 17:00
  • @HamzehSoboh I've edited as in the case of InstanceIdResult it may not be necessary, but to answer to your question take a look at this [link](https://developers.google.com/android/guides/tasks#activity-scoped_listeners) about [activity scoped listeners](https://developers.google.com/android/guides/tasks#activity-scoped_listeners). – Facundo Larrosa Jul 13 '18 at 14:12
  • @Facundo, before onNewToken was introduced, onTokenRefresh was supposed to call whenever system invalidate the tokens. Is this behavior same for onNewToken ? Will onNewToken be called when my existing tokens need to be refreshed or when system will invalid ny existing tokens ? – Hey You Sep 16 '18 at 07:07
  • @HeyYou good question. I didn't found any documentation specifying this behavior. Gonna dive a little bit more on this matter. – Facundo Larrosa Sep 17 '18 at 01:30
  • @Facundo Documentation says "Called when a new token for the default Firebase project is generated.This is invoked after app install when a token is first generated, and again if the token changes." Intresting part is "again if token changes" does it means it will also be called when system determine that token need to be refresh ? – Hey You Sep 17 '18 at 01:46
  • @HeyYou sure, it is called every time token is refreshed. – Facundo Larrosa Sep 19 '18 at 03:02
  • 6
    This is not a solution when you need the token outside a callback. This is not functional. – Pedro Paulo Amorim Sep 25 '18 at 10:39
  • 2
    @PedroPauloAmorim I agree. newToken doesn't seem to get called 100% so another method to retrieve the existing token is required – behelit Mar 29 '19 at 00:12
  • 1
    @behelit My solution was to keep trying to get it until the system returns a valid value (aka recursive). – Pedro Paulo Amorim Apr 01 '19 at 11:13
  • Is there any problem if I add FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(...) in Activity launcher onCreate() so It will be called all the time user opens my app? – Carlos Eduardo Ki Lee Jan 22 '20 at 19:54
  • 1
    @CarlosEduardoKiLee it shouldn't be any problem. It may not be a best practice as it will return the same value until the token is refreshed. – Facundo Larrosa Jan 26 '20 at 04:08
  • 1
    this deprecated again – DjongaNelson Lontrowski Nov 23 '20 at 11:51
  • 1
    FirebaseInstallations.getInstance().getToken(true) DOES NOT GIVE MESSAGING TOKEN, IT CHANGES AFTER EVERY LAUNCH – El Jazouli Mar 04 '21 at 16:14
35

FirebaseInstanceIdService was deprecated .!

just override onNewToken() in FirebaseMessagingService

public class LatestFirebaseMessagingService extends FirebaseMessagingService {

@Override
public void onNewToken(String mToken) {
    super.onNewToken(mToken);
    Log.e("TOKEN",mToken);
}

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    super.onMessageReceived(remoteMessage);
}} 

InAndroidManifest.xml

<service
        android:name=".LatestFirebaseMessagingService"
        android:stopWithTask="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
</service>

getToken() This is also deprecated.!

if you need to get token in your activity use the below code.

FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener( MyActivity.this,  new OnSuccessListener<InstanceIdResult>() {
     @Override
     public void onSuccess(InstanceIdResult instanceIdResult) {
           String mToken = instanceIdResult.getToken();
           Log.e("Token",mToken);
     }
 });
KUSHA B K
  • 971
  • 9
  • 20