Firebase Fcm Force Ontokenrefresh() to Be Called

Firebase FCM force onTokenRefresh() to be called

The onTokenRefresh() method is going to be called whenever a new token is generated. Upon app install, it will be generated immediately (as you have found to be the case). It will also be called when the token has changed.

According to the FirebaseCloudMessaging guide:

You can target notifications to a single, specific device. On initial
startup of your app, the FCM SDK generates a registration token for
the client app instance.

Screenshot

Source Link:
https://firebase.google.com/docs/notifications/android/console-device#access_the_registration_token

This means that the token registration is per app. It sounds like you would like to utilize the token after a user is logged in. What I would suggest is that you save the token in the onTokenRefresh() method to internal storage or shared preferences. Then, retrieve the token from storage after a user logs in and register the token with your server as needed.

If you would like to manually force the onTokenRefresh(), you can create an IntentService and delete the token instance. Then, when you call getToken, the onTokenRefresh() method will be called again.

Example Code:

public class DeleteTokenService extends IntentService
{
public static final String TAG = DeleteTokenService.class.getSimpleName();

public DeleteTokenService()
{
super(TAG);
}

@Override
protected void onHandleIntent(Intent intent)
{
try
{
// Check for current token
String originalToken = getTokenFromPrefs();
Log.d(TAG, "Token before deletion: " + originalToken);

// Resets Instance ID and revokes all tokens.
FirebaseInstanceId.getInstance().deleteInstanceId();

// Clear current saved token
saveTokenToPrefs("");

// Check for success of empty token
String tokenCheck = getTokenFromPrefs();
Log.d(TAG, "Token deleted. Proof: " + tokenCheck);

// Now manually call onTokenRefresh()
Log.d(TAG, "Getting new token");
FirebaseInstanceId.getInstance().getToken();
}
catch (IOException e)
{
e.printStackTrace();
}
}

private void saveTokenToPrefs(String _token)
{
// Access Shared Preferences
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = preferences.edit();

// Save to SharedPreferences
editor.putString("registration_id", _token);
editor.apply();
}

private String getTokenFromPrefs()
{
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
return preferences.getString("registration_id", null);
}
}

EDIT

FirebaseInstanceIdService

public class FirebaseInstanceIdService extends Service

This class is deprecated. In favour of overriding
onNewToken in FirebaseMessagingService. Once that has been
implemented, this service can be safely removed.

onTokenRefresh() is deprecated. Use onNewToken() in MyFirebaseMessagingService

public class MyFirebaseMessagingService extends FirebaseMessagingService {

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

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

Android Firebase Cloud Messaging (FCM) onTokenRefresh() never called and getToken() returning null

I have found out that occurrence of the problem depends on the firebase SDK version that is specified in the app level build.gradle: onTokenRefresh is no longer called as of SDK version 11.6.0. Looking at the release notes, this version has the following change related to token generation:

"Improved FCM token fetch logic so that the FCM token is now created faster and with less battery drain."

I assume that the FCM related changes in this release are related to my problem, and will issue a bug report.

Update: Firebase Support investigated the problem and reported back that the origin of the problem was the following lines in my AndroidManifest:

<uses-permission
android:name="android.permission.WAKE_LOCK"
tools:node="remove"/>

which I once added to avoid requesting "prevent phone from sleeping permission". Without these lines in the manifest the FCM token is refreshed without issues in combination with SDK 11.8.0.

Android FCM onTokenRefresh() is only called in emulator

Please make sure that your device is connected to the internet.
It may take a few seconds to generate the token so check the token not directly after the start of the application.

Firebase onTokenRefresh() is not called


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) {

}}

FCM - onTokenRefresh() is never called


FCM clients require devices running Android 2.3 or higher that also
have the Google Play Store app installed, or an emulator running
Android 2.3 with Google APIs.

onTokenRefresh() is never called on first app install

This problem can occur when the device or emulator is running an old version of Google Play Services that is not compatible with the version of the Firebase libraries used. When this condition exists, the logcat will contain this warning message:

W/GooglePlayServicesUtil: Google Play services out of date.  Requires XXXXXXXX but found XXXXXXXX

The solution is to update Google Play Services, or downgrade the version of Firebase.

Because the Firebase APIs require a compatible version of Google Play Services, it's good practice to confirm the presence of a compatible version during app initialization using GoogleApiAvailability.

What is the solution to Firebase onTokenRefresh not being called on-time [Android]?

It is perhaps sure that token would be generated at very starting of the app. This token would not be re-generate / re-create without some conditions to fulfill.
You can store this token using sharedpreference and can use later.
I am doing like this and seems getting token for users when I need.

****If token refresh takes that much long time then you could update user info later after getting token. - This could be the safest solution to avoid null value.

In my sense update user info all time after app launching (if token value not null) and store token value in sharedpreference inside

onTokenRefresh()

that user value would be always updated if it changes in any situation.



Related Topics



Leave a reply



Submit