Firebase onTokenRefresh() is not called

72,121

Solution 1

onTokenRefresh in FirebaseInstanceIdService is only called when a new token is generated. If your app was previously installed and generated a token then onTokenRefresh would not be called. Try uninstalling and reinstalling the app to force the generation of a new token, this would cause onTokenRefresh to be called.

Also be sure that your FirebaseInstanceIdService is properly defined in your AndroidManifest.xml

In your Manifest File.

 <service
        android:name="com.bnt.etailers.fcm.MyFireBaseInstanceIDService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
        </intent-filter>
    </service>

    <service
        android:name="com.bnt.etailers.fcm.GCMNotificationIntentService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>

FirebaseInstanceIdService class

public class MyFireBaseInstanceIDService extends FirebaseInstanceIdService {


private static final String TAG = MyFireBaseInstanceIDService.class.getSimpleName();

@Override
public void onTokenRefresh() {
    // Get updated InstanceID token.
    String refreshedToken = FirebaseInstanceId.getInstance().getToken();
    Log.d(TAG, "Refreshed token: " + refreshedToken);

    if (refreshedToken!=null) {
        SettingPreferences.setStringValueInPref(this, SettingPreferences.REG_ID, refreshedToken);
    }
    // TODO: Implement this method to send any registration to your app's servers.
    sendRegistrationToServer(refreshedToken);
}
// [END refresh_token]

/**
 * Persist token to third-party servers.
 *
 * Modify this method to associate the user's FCM InstanceID token with any server-side account
 * maintained by your application.
 *
 * @param token The new token.
 */
private void sendRegistrationToServer(String token) {
    // Add custom implementation, as needed.
}}

FirebaseMessagingService class.

public class GCMNotificationIntentService extends FirebaseMessagingService {
// Sets an ID for the notification, so it can be updated


public GCMNotificationIntentService() {
    super();
}


@Override
public void onMessageReceived(RemoteMessage message) {

}}

Solution 2

I had the same problem like you. My mistake was the following: I placed my <service> tags outside the <application> tag in the AndroidManifest.xml file.

Now mine looks like this:

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

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

    <service
        android:name=".MyFirebaseInstanceIDService">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
        </intent-filter>
    </service>
</application>

And it works without any problem.

Solution 3

Yes this might happen some times.

Please call the following method wherever you want to get your fcm id.

    try {
            String refreshedToken = FirebaseInstanceId.getInstance().getToken();
            Log.d("Firbase id login", "Refreshed token: " + refreshedToken);
        } catch (Exception e) {
            e.printStackTrace();
        }

Solution 4

Try re-install the app, by uninstall it first from your device or emulator. It will then generate a new token, thus onTokenRefresh() will be called again.

Solution 5

In my case I forgot to add internet permission in manifest,

<uses-permission android:name="android.permission.INTERNET" />

Hope most people won't make this mistake.

Share:
72,121
natsumiyu
Author by

natsumiyu

Updated on July 05, 2022

Comments

  • natsumiyu
    natsumiyu almost 2 years

    In my MainActivityin my log, I can see the token using FirebaseInstanceId.getInstance().getToken() and it display the generated token. But it seems like in my MyFirebaseInstanceIDService where it is extends to FirebaseInstanceIdService, the onTokenRefresh() is not called, where in this function it was said that the token is initially generated here. I needed to call sendRegistrationToServer() that's why I'm trying to know why it doesn't go in the onTokenRefresh().

    Here is my code

    public class MyFirebaseInstanceIDService  extends FirebaseInstanceIdService {
    
    
    @Override
    public void onTokenRefresh() {
        // Get updated InstanceID token.
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
        Log.d(TAG, "Refreshed token: " + refreshedToken);
    
            sendRegistrationToServer(refreshedToken);
        }
    }
    
  • viplezer
    viplezer almost 8 years
    Credits goes to this thread: stackoverflow.com/questions/37351354/…
  • WenChao
    WenChao almost 8 years
    The documentation seems confusing(firebase.google.com/docs/cloud-messaging/android/c‌​lient), it says The registration token may change when:The app deletes Instance ID, and if I manually call FirebaseInstanceId.getInstance().deleteInstanceId(); I was expecting a new token generated, but nothing actually happens in this case, onTokenRefresh is never called.
  • Juan
    Juan over 7 years
    great answer...is this the facebook id that gets returned?.......cause I'm trying to do that and I'm getting a very large token
  • viplezer
    viplezer over 7 years
    Facebook? Firebase? You get the token for Firebase Cloud Messaging in your FirebaseInstanceIDService subclass's onTokenRefresh method and yes, it is a long string, my token is 152 character long.
  • Vitaliy A
    Vitaliy A about 7 years
    Good one. After few reinstalls, token stop to refresh, but direct getToken did return correct token.
  • Alexander Farber
    Alexander Farber almost 7 years
    Why save the token to shared preferences - if you can call FirebaseInstanceId.getInstance().getToken() at any time to get its value?
  • Salis
    Salis almost 7 years
    @WenChao make sure you call InstanceID of the playservice by InstanceID.getInstance(this).deleteInstanceID() and call it from background thread, after u successfully delete it, call InstanceID.getInstance(this).getID() to generate new token
  • jet_choong
    jet_choong almost 7 years
    this is the solution for me.
  • Sterling Diaz
    Sterling Diaz over 6 years
    @Alexander Farber, it's because you can only get the token once, you need to persist it to use it later. For example, I'm doing an app that does not need the user to be registered, but it he wants to subscribe to certain update, he can register, I can send the token of his device with his data, but if I would got the token when he first installed the app, that wouldn't be possible.
  • Pierre
    Pierre about 6 years
    Thread t = new Thread() will solve the MAIN_THREAD Exception
  • Matt Mc
    Matt Mc about 6 years
    You say "android:exported=true" but the code sample says "android:exported=false". Which is it?
  • psydj1
    psydj1 about 6 years
    sorry man, updated and expanded, thanks for pointing that out
  • Sagar
    Sagar over 5 years
    @viplezer on my KITKAT not able to get token above its working. please help
  • Sagar
    Sagar over 5 years
    I am testing it on kitkat and above devices on kitkat onTokenRefresh method is not triggering FCM version 11.6.2
  • Sagar
    Sagar over 5 years
    on kitkat device not able to get token FirebaseInstanceId: Token retrieval failed: SERVICE_NOT_AVAILABLE
  • Hoque MD Zahidul
    Hoque MD Zahidul over 5 years
    Have you checked all of the avobe issue that's I have mentioned here?
  • Sagar
    Sagar over 5 years
    yes only on kitkat device its not working rest above kitkat its working my FCM version is 11.6.2
  • Sagar
    Sagar over 5 years
    Changing FCM version to 10.2.1 worked for me my targetSdkVersion is 27 and minimum is 16