android - Firebase onTokenRefresh() is not called

android - Firebase onTokenRefresh() is not called

Iorwerth Endrit Author: Iorwerth Endrit Date: 2022-08-18
android - Firebase onTokenRefresh() is not called

All you need to know about android - Firebase onTokenRefresh() is not called , in addintion to android - FirebaseInstanceIdService does not get called , Flutter 2.0 with Firebase Cloud Messaging: onMessage not called on Android , android - Firebase onMessageReceived not called when app in background , android - Firebase onMessageReceived(RemoteMessage remoteMessage), is not called when the app is in background

  1. android - Firebase onTokenRefresh() is not called
  2. Question:

    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);
        }
    }
    


    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();
            }
    

  3. android - FirebaseInstanceIdService does not get called
  4. Question:

    I followed the examples on the internet and reviewed many questions here and on other websites

    I built my application so it handles FCM Notifications, but I still cant find out why FirebaseInstanceIdService does not get called.

    I declared it in AndroidManifest.xml

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

    My Service is

    public class InstanceService extends FirebaseInstanceIdService {
        private static final String REG_Token="REG_Token";
    
        @Override
        public void onTokenRefresh() {
    
            String recent_token= FirebaseInstanceId.getInstance().getToken(); // get token from the server
    
            Log.d(REG_Token,recent_token); // show device token in Logcat View
    
        }
    

    I look at Logcat but there is no REG_Token there.

    I tried to debug the code and stopped it at Log.d(REG_Token,recent_token);, but it did not stop there.

    I think the service is not called at all and I can't find out why.


    Solution 1:

    From this documentation

    The registration token may change when:

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

    It means that the onTokenRefresh() method is not called every time the app is opened but only when one of those 4 events occurred.

    The simplest way is to uninstall the app and then install the app again. After it's installed, open the app and then look at the logcat (based on your code).

    Hope this helps :)

  5. Flutter 2.0 with Firebase Cloud Messaging: onMessage not called on Android
  6. Question:

    I got a problem with Firebase Cloud Messaging onMessage in Flutter 2.0.

    The function

    FirebaseMessaging.onMessage.listen((RemoteMessage message) { ... }

    is not called when receiving a message in the foreground. However, the logs say

    broadcast received for message

    At the first received message, I get additional warnings, like:

    Accessing hidden method Landroid/os/WorkSource

    But the warnings disappear on subsequent messages.

    The funny thing is, that

    FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);

    works.

    If I send the app to the background, I get a notification and the defined method is called.

    Code

    @override
    void initState() {
        initializeFlutterFire()
            .then((value) => subscribeToMessages);
    
        super.initState();
    }
    
    Future<void> initializeFlutterFire() async {
        try {
            Firebase.initializeApp();
            setState(() {
                _initialized = true;
                print("Firebase has been initialized");
            });
        } catch (e) {
           setState(() {
               _error = true;
           });
        }
    }
    
    void subscribeToMessages() {
        // The following handler is called, when App is in the background.
        FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
    
        // The following function is not called, when a message was received by the device.
        FirebaseMessaging.onMessage.listen((RemoteMessage message) {
            print('Got a message whilst in the foreground!');
            print('Message data: ${message.data}');
    
            if (message.notification != null) {
                print('Message also contained a notification: ${message.notification}');
            }
        });
    }
    
    Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
        print('message from background handler');
        print("Handling a background message: ${message.messageId}");
    }
    

    I got the feeling, that there is no subscription from onMessage().listen(...) and that's why nothing is executed.

    Do you have any suggestions, what I am doing wrong?

    Thanks in advance, Uwe

    Environment

    Firebase Console Cloud Messaging

    on

    Huawei P20 and Samsung Galaxy Tab A 10, both on Android 10.

    pubspec.yaml

    firebase_core: "^1.0.1"
    firebase_messaging: "^9.0.0"
    

    android/build.gradle

    dependencies {
        ...
        classpath 'com.google.gms:google-services:4.3.5'
    

    android/app/build.gradle

    apply plugin: 'com.android.application'
    apply plugin: 'com.google.gms.google-services'
    ...
    
    android {
        compileSdkVersion 30
        ...
        defaultConfig {
            minSdkVersion 16
            targetSdkVersion 30
            ...
    

    AndroidManifest.xml

    <activity ...>
        ...
        <intent-filter>
            <action android:name="FLUTTER_NOTIFICATION_CLICK" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT"/>
        </intent-filter>
    </activity>
    

    flutter doctor

    Doctor summary (to see all details, run flutter doctor -v):
    [✓] Flutter (Channel beta, 2.0.2, on macOS 11.2.1 20D75 darwin-x64, locale de)
    [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    [!] Xcode - develop for iOS and macOS
        ✗ Xcode installation is incomplete; a full installation is necessary for iOS development.
        Download at: https://developer.apple.com/xcode/download/
        Or install Xcode via the App Store.
        Once installed, run:
            sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
            sudo xcodebuild -runFirstLaunch
    [✓] Chrome - develop for the web
    [✓] Android Studio
    [✓] Android Studio (version 4.1)
    [✓] IntelliJ IDEA Community Edition (version 2020.1.2)
    [✓] VS Code (version 1.53.0)
    [✓] Connected device (3 available)
    
    ! Doctor found issues in 1 category.
    


    Solution 1:

    There is an issue with firebase_messaging 9.0.0 plugin.

    If you navigate to the definition of the factory RemoteMessage.fromMap() Using Cmd+Click or Ctrl+Click while hovering over the RemoteMessage class with the mouse), in the return statement, change

    contentAvailable: map['contentAvailable'], 
    mutableContent: map['mutableContent'],
    

    to

    contentAvailable: map['contentAvailable'] ?? false,
    to mutableContent: map['mutableContent'] ?? false,
    

    You may have to confirm that you want to modify the package. This should get you through until the package is updated.

    Solution 2:

  7. android - Firebase onMessageReceived not called when app in background
  8. Question:

    I'm working with Firebase and testing sending notifications to my app from my server while the app is in the background. The notification is sent successfully, it even appears on the notification centre of the device, but when the notification appears or even if I click on it, the onMessageReceived method inside my FCMessagingService is never called.

    When I tested this while my app was in the foreground, the onMessageReceived method was called and everything worked fine. The problem occurs when the app is running in the background.

    Is this intended behaviour, or is there a way I can fix this?

    Here is my FBMessagingService:

    import android.util.Log;
    
    import com.google.firebase.messaging.FirebaseMessagingService;
    import com.google.firebase.messaging.RemoteMessage;
    
    public class FBMessagingService extends FirebaseMessagingService {
    
        @Override
        public void onMessageReceived(RemoteMessage remoteMessage) {
            Log.i("PVL", "MESSAGE RECEIVED!!");
            if (remoteMessage.getNotification().getBody() != null) {
                Log.i("PVL", "RECEIVED MESSAGE: " + remoteMessage.getNotification().getBody());
            } else {
                Log.i("PVL", "RECEIVED MESSAGE: " + remoteMessage.getData().get("message"));
            }
        }
    }
    


    Solution 1:

    This is working as intended, notification messages are delivered to your onMessageReceived callback only when your app is in the foreground. If your app is in the background or closed then a notification message is shown in the notification center, and any data from that message is passed to the intent that is launched as a result of the user tapping on the notification.

    You can specify a click_action to indicate the intent that should be launched when the notification is tapped by the user. The main activity is used if no click_action is specified.

    When the intent is launched you can use the

    getIntent().getExtras();
    

    to retrieve a Set that would include any data sent along with the notification message.

    For more on notification message see docs.

    Solution 2:

    Remove notification field completely from your server request. Send only data and handle it in onMessageReceived() otherwise your onMessageReceived() will not be triggered when app is in background or killed.

    Don't forget to include "priority": "high" field in your notification request. According to the documentation: data messages are sent with a normal priority, thus they will not arrive instantly; it could also be the problem.

    Here is what I am sending from server

    {
      "data":{
        "id": 1,
        "missedRequests": 5
        "addAnyDataHere": 123
      },
      "to": "fhiT7evmZk8:APA91bFJq7Tkly4BtLRXdYvqHno2vHCRkzpJT8QZy0TlIGs......",
      "priority": "high"
    }
    

    So you can receive your data in onMessageReceived(RemoteMessage message) like this....let say I have to get id

    Object obj = message.getData().get("id");
            if (obj != null) {
                int id = Integer.valueOf(obj.toString());
            }
    

    Solution 3:

    this method handleIntent() has been depreciated, so handling a notification can be done as below:

    1. Foreground State: The click of the notification will go to the pending Intent's activity which you are providing while creating a notification pro-grammatically as it generally created with data payload of the notification.

    2. Background/Killed State - Here, the system itself creates a notification based on notification payload and clicking on that notification will take you to the launcher activity of the application where you can easily fetch Intent data in any of your life-cycle methods.

  9. android - Firebase onMessageReceived(RemoteMessage remoteMessage), is not called when the app is in background
  10. Question:

    In Firebase onMessageReceived(RemoteMessage remoteMessage), this method will be called when your app is in Foreground. So, on clicking the notification you can open a different Activity, say NotiicationActivity.

    But what if your app is in background, then this method will not be called, and on clicking the notification only a Launcher Activity will be opened.

    So how to open the NotificationActivity on clicking the notification even if our app is in background.

    My Code is this :

    public class MyFirebaseMessagingService extends FirebaseMessagingService {
    
        private static final String TAG = "MyFirebaseMsgService";
    
        @Override
        public void onMessageReceived(RemoteMessage remoteMessage) {
            Log.d(TAG, "From: " + remoteMessage.getFrom());
    
            if (remoteMessage.getData().size() > 0) {
                Log.d(TAG, "Message data payload: " + remoteMessage.getData());
            }
    
            if (remoteMessage.getNotification() != null) {
                Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
            }
    
            sendNotification(remoteMessage.getNotification().getBody());
    
        }
    
        private void sendNotification(String messageBody) {
            Intent intent = new Intent(this, NewActivity.class);
            intent.putExtra("key", messageBody);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                PendingIntent.FLAG_ONE_SHOT);
            Bitmap icon2 = BitmapFactory.decodeResource(getResources(),
                R.mipmap.ic_launcher);
    
            Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle("FCM Sample")
            .setContentText(messageBody)
            .setAutoCancel(true)
            .setLargeIcon(icon2)
            .setSound(defaultSoundUri)
            .setContentIntent(pendingIntent);
    
            NotificationManager notificationManager =
            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    
            notificationManager.notify(new Random().nextInt() /* ID of notification */, notificationBuilder.build());
        }
    }
    


    Solution 1:

    onMessageReceived is only triggered when the application is in foreground. If the app is backgrounded, you may still be able to receive the notification but onMessageReceived will not be triggered.

    So my suggestion, on the receiving activity, you can still get the data from the notification by using:

    getIntent().getExtras();
    

    This should work accordingly. Hope this helps :)

    Solution 2:

    try and follow below link :

    Firebase Cloud Messaging for Android

    Solution 3:

    In your sendNotification() method :

     private void showNotification(String message){
        Intent intent=new Intent(this, NotificationActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.putExtra("key", messageBody);
        PendingIntent pendingIntent=PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
    
        NotificationCompat.Builder builder=new NotificationCompat.Builder(this)
                .setAutoCancel(true)
                .setContentTitle("FCM Sample")
                .setContentText(message)
                .setLargeIcon(icon2)
                .setContentIntent(pendingIntent);
        NotificationManager manager=(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        manager.notify(0,builder.build());
    
    }