diff --git a/cleverpush/src/main/java/com/cleverpush/CleverPushPreferences.java b/cleverpush/src/main/java/com/cleverpush/CleverPushPreferences.java index 4f5007bf..7b1ae6c0 100644 --- a/cleverpush/src/main/java/com/cleverpush/CleverPushPreferences.java +++ b/cleverpush/src/main/java/com/cleverpush/CleverPushPreferences.java @@ -3,6 +3,7 @@ public class CleverPushPreferences { public static final String FCM_TOKEN = "CleverPush_FCM_TOKEN"; + public static final String SYNCED_FCM_TOKEN = "CleverPush_SYNCED_FCM_TOKEN"; public static final String HMS_TOKEN = "CleverPush_HMS_TOKEN"; public static final String ADM_TOKEN = "CleverPush_ADM_TOKEN"; public static final String CHANNEL_ID = "CleverPush_CHANNEL_ID"; diff --git a/cleverpush/src/main/java/com/cleverpush/manager/SubscriptionManagerFCM.java b/cleverpush/src/main/java/com/cleverpush/manager/SubscriptionManagerFCM.java index 1e974238..3e34ede9 100755 --- a/cleverpush/src/main/java/com/cleverpush/manager/SubscriptionManagerFCM.java +++ b/cleverpush/src/main/java/com/cleverpush/manager/SubscriptionManagerFCM.java @@ -166,32 +166,62 @@ public void subscribe(JSONObject channelConfig, SubscribedCallbackListener subsc @Override public void checkChangedPushToken(JSONObject channelConfig, String changedToken) { SharedPreferences sharedPreferences = SharedPreferencesManager.getSharedPreferences(this.context); - String existingToken = sharedPreferences.getString(CleverPushPreferences.FCM_TOKEN, null); + + // IMPORTANT: + // Compare against LAST SUCCESSFULLY SYNCED token, + // not the latest locally cached Firebase token. + String existingToken = sharedPreferences.getString(CleverPushPreferences.SYNCED_FCM_TOKEN, null); if (existingToken == null) { - return; + Logger.d(LOG_TAG, "No synced FCM token found. Syncing current token."); } new Thread(() -> { String senderId = this.getSenderIdFromConfig(channelConfig); + if (senderId == null) { Logger.e(LOG_TAG, "SubscriptionManager: Getting FCM Sender ID failed"); return; } + try { String newToken = changedToken != null ? changedToken : getTokenAttempt(senderId); - if (newToken != null && !newToken.equals(existingToken)) { - this.syncSubscription(newToken, new SubscribedCallbackListener() { - @Override - public void onSuccess(String subscriptionId) { - Logger.i(LOG_TAG, "Synchronized new FCM token: " + newToken); - } - - @Override - public void onFailure(Throwable exception) { - - } - }, senderId); + + if (newToken == null) { + Logger.d(LOG_TAG, "checkChangedPushToken: no FCM token available yet, will retry on next sync."); + return; + } + + boolean forcedTokenRefresh = changedToken != null; + boolean tokenMissingLocally = existingToken == null; + boolean tokenChanged = !newToken.equals(existingToken); + + if (forcedTokenRefresh || tokenMissingLocally || tokenChanged) { + + this.syncSubscription( + newToken, + new SubscribedCallbackListener() { + + @Override + public void onSuccess(String subscriptionId) { + Logger.i(LOG_TAG, "Synchronized FCM token: " + newToken); + + sharedPreferences.edit() + // latest local token + .putString(CleverPushPreferences.FCM_TOKEN, newToken) + // last successfully synced token + .putString(CleverPushPreferences.SYNCED_FCM_TOKEN, newToken) + .apply(); + } + + @Override + public void onFailure(Throwable exception) { + Logger.e(LOG_TAG, "Failed to sync FCM token", exception); + } + }, + senderId + ); + } else { Logger.d(LOG_TAG, "FCM token has not changed: " + newToken); } diff --git a/cleverpush/src/main/java/com/cleverpush/service/CleverPushFcmListenerService.java b/cleverpush/src/main/java/com/cleverpush/service/CleverPushFcmListenerService.java index 6a42b47b..26260037 100644 --- a/cleverpush/src/main/java/com/cleverpush/service/CleverPushFcmListenerService.java +++ b/cleverpush/src/main/java/com/cleverpush/service/CleverPushFcmListenerService.java @@ -56,15 +56,24 @@ public void onNewToken(@NonNull String token) { Logger.d(LOG_TAG, "FCM: onNewToken"); SharedPreferences sharedPreferences = SharedPreferencesManager.getSharedPreferences(this); + + // Always store latest local token immediately. + // This ensures we never lose token rotations. + sharedPreferences.edit().putString(CleverPushPreferences.FCM_TOKEN, token).apply(); + String subscriptionId = sharedPreferences.getString(CleverPushPreferences.SUBSCRIPTION_ID, null); if (subscriptionId == null) { - Logger.d(LOG_TAG, "CleverPushFcmListenerService onNewToken: There is no subscription for CleverPush SDK."); + Logger.d(LOG_TAG, "CleverPushFcmListenerService onNewToken: no subscription yet, token cached for next subscribe."); return; } CleverPush cleverPush = CleverPush.getInstance(this); + cleverPush.getChannelConfig( - (JSONObject channelConfig) -> cleverPush.getSubscriptionManager().checkChangedPushToken(channelConfig, token)); + (JSONObject channelConfig) -> + cleverPush.getSubscriptionManager() + .checkChangedPushToken(channelConfig, token) + ); } }