firebase_messaging how to clear notification?

3,646

Solution 1

I was having problems with this too. I have this workaround: What i did was to create a class with an static bool and static method:

class MessagingWidget {

  static bool _isConfigured = false;


  static void configuringFirebase(User currentUser, BuildContext context){
      

      final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
      if (!_isConfigured) {
      _firebaseMessaging.configure(
      onMessage: (Map<String, dynamic> message) async {
        print("onMessage: $message");
        final notification = message['notification'];
      },
      onLaunch: (Map<String, dynamic> message) async {
        print("onLaunch: $message");

        final notification = message['data'];
        if(notification['title']!=null){
            if(notification['title']=="Testo"){
              goToAppointmentsScreen(currentUser,context);

            }
          }
      },
      onResume: (Map<String, dynamic> message) async {
        print("onResume: $message");

        final notification = message['data'];
        if(notification['title']!=null){
            if(notification['title']=="Testo"){
              goToAppointmentsScreen(currentUser,context);

            }
          }
      },
    );
    _isConfigured = true;
    }

  }
    
    
  }

  void goToAppointmentsScreen(User currentUser1, BuildContext context1) async {
    final bool backFromAppointmentsScreen=await Navigator.push(
            context1,
            MaterialPageRoute(builder: (context) => Appointment( 
              currentUser1),
            ),
            );
  }

Then I called this method in my init from the routing widget:

@override
  void initState(){
    super.initState();
    refreshServices();
    getDirectionBasedOnLocation();
    MessagingWidget.configuringFirebase(currentUser, context);
}

I hope this helps you

Solution 2

What I do to prevent onLaunch and onResume method to run again and again is to check the current notification with the last notification (I use shared_preferences)

Here's the snippet:

_firebaseMessaging.configure(
    onMessage: (Map<String, dynamic> message) async {
      print('on message $message');
      onMessageReceived(context, message);
    },
    onResume: (Map<String, dynamic> message) async {
      print('on resume $message');
      onLaunch(context, message);
    },
    onLaunch: (Map<String, dynamic> message) async {
      print('on launch $message');
      onLaunch(context, message);
    },
  );

.
.
.

void onLaunch(BuildContext context, Map<String, dynamic> remoteMessage) async {
  var pref = SharedPreferences.getInstance();

  var data = remoteMessage['data'] ?? remoteMessage;
  String lastData = '';

  await pref.then((prefs) {
    lastData = prefs.get('remote_message');
  });

  if ((data['type'] != null || data['id'] != null) &&
      data.toString() != lastData) {

    toDetailPageFromPush(
      context,
      data['type'],
      data['id'],
    );
    pref.then((prefs) {
      prefs.setString('remote_message', data.toString());
    });
  } else {
    print('on launch error $remoteMessage');
  }
}

Solution 3

Here is another solution, using the message_id which is and unique value from the notification, so we can save the last id of the notification using shared prefrerences and compare with the current notification:

processNotification(message, BuildContext context) async {
 try {

  SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
 
  String lastMessageId = sharedPreferences.getString('last_message_id');
  String currentMessageId = message['data']['google.message_id'];

  //COMPARE NOTIFICATIONS ID
  if(currentMessageId != lastMessageId) {
    
     //SET LAST NOTIFICATION ID
     sharedPreferences.setString('last_message_id', currentMessageId);
 
     //SHOW A DIALOG OR NAVIGATE TO SOME VIEW, IN THIS CASE TO A VIEW
     String screen = message['data']['screen'];
     Navigator.of(context).pushNamed(screen);
  }
} catch (e) {
  print('ERROR PROCESSING NOTIFICATION');
  print(e);
 }
}

Now we can call this function in the config:

 _firebaseMessaging.configure(
  onMessage: (Map<String, dynamic> message) async {
    print('on message $message');
    processNotification(context,message);
  },
  onResume: (Map<String, dynamic> message) async {
    print('on resume $message');
    processNotification(context,message);
  },
  onLaunch: (Map<String, dynamic> message) async {
    processNotification(context,message);
  },
);
Share:
3,646
Govaadiyo
Author by

Govaadiyo

Updated on December 11, 2022

Comments

  • Govaadiyo
    Govaadiyo over 1 year

    I'm using firebase_messaging When notification comes, I'm displaying alert dialog. Below are my code.

    showNotification(BuildContext context) {
        _firebaseMessaging.configure(
          onMessage: (Map<String, dynamic> message) async {
            print('on message $message');
            _showPushNotificationDialog(message['notification']['title'],
                message['notification']['body'], context);
          },
          onResume: (Map<String, dynamic> message) async {
            print('on resume $message');
            _showPushNotificationDialog(
                message['data']['title'], message['data']['body'], context);
          },
          onLaunch: (Map<String, dynamic> message) async {
            print('on launch $message');
            _showPushNotificationDialog(
                message['data']['title'], message['data']['body'], context);
          },
        );
      }
    

    Where _showPushNotificationDialog method will call each times when onMessage, onResume, and onLaunch method call.

    Facing issue like when my app is in background or terminate mode and notification will come and will tap on notification tray all works good. But when I go on other page and come back to previous one all time _firebaseMessaging.configure(.... method call and its has data so each time my alert dialog pups up.

    So how can I clear notification that was clicked by notification tray?

  • Govaadiyo
    Govaadiyo almost 5 years
    This method calling from initState :)
  • ehhc
    ehhc almost 5 years
    @Govaadiyo : Maybe i ran into the same problem as you did (now i think i might misunderstood your initial question). I opened a github issue but didn’t get an answer from the official flutter devs. Nonetheless, i found a workaround which seems to work for me. Maybe it helps you as well? You can find my problem and my work around here: github.com/flutter/flutter/issues/32698#issuecomment-4947663‌​29
  • Itamar Garcia
    Itamar Garcia about 3 years
    It is not the best solution, but it works, thanks