Flutter: Local Notifications Plugin showing notification twice

2,329

Just in case someone stumbles across this same issue. I re-read the documentation on FlutterFire where it mentions if you have the current up-to-date Flutter SDK and Firebase, then it will try to display it automatically. My mistake was that I implemented FlutterLocalNotifications in addition to this and I was receiving two notifications where one was manual and the other automatic.

When sending a message to your device, make sure it is a notification rather than data. The documentation mentions that if you send data it will likely be ignored as a push notification. Only use it to send packets of data to the app instead.

Share:
2,329
pythonNovice
Author by

pythonNovice

Updated on December 01, 2022

Comments

  • pythonNovice
    pythonNovice over 1 year

    I am receiving notification from my server at a specific time to show users a notification. However, whenever my device receives a message from Firebase Cloud Messaging FlutterLocalNotificationsPlugin ends up showing two notifications as seen below.

    enter image description here

    I already confirmed that I am receiving one notification from my server, its just that somewhere in the front end its being handled incorrectly I think.

    Here is my code where I am calling this in the background

    main

    Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
      // If you're going to use other Firebase services in the background, such as Firestore,
      // make sure you call `initializeApp` before using other Firebase services.
      await Firebase.initializeApp();
      print('Handling a background message ${message.messageId}');
      if (message.notification != null) {
        print(message.notification.title);
        print(message.notification.body);
        flutterLocalNotificationsPlugin.show(
            message.notification.hashCode,
            message.notification.title,
            message.notification.body,
            NotificationDetails(
              android: AndroidNotificationDetails(
                channel.id,
                channel.name,
                channel.description,
                icon: 'launch_background',
              ),
              iOS: IOSNotificationDetails()
            ));
      }
    
      // Create a notification for this
    }
    
    
    const AndroidNotificationChannel channel = AndroidNotificationChannel(
      'high_importance_channel', // id
      'High Importance Notifications', // title
      'This channel is used for important notifications.', // description
      importance: Importance.high,
    );
    
    final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
        FlutterLocalNotificationsPlugin();
    
    // Starting FlutterFire through the suggestion found here
    // https://firebase.flutter.dev/docs/overview
    Future<void> main() async {
      WidgetsFlutterBinding.ensureInitialized();
      await Firebase.initializeApp();
      FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
    
      /// Create an Android Notification Channel.
      /// We use this channel in the `AndroidManifest.xml` file to override the
      /// default FCM channel to enable heads up notifications.
      await flutterLocalNotificationsPlugin
          .resolvePlatformSpecificImplementation<
              AndroidFlutterLocalNotificationsPlugin>()
          ?.createNotificationChannel(channel);
    
      /// Update the iOS foreground notification presentation options to allow
      /// heads up notifications.
      await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
        alert: true,
        badge: true,
        sound: true,
      );
    
      runApp(MyApp());
    }
    
    class MyApp extends StatefulWidget {
      MyApp({Key key}) : super(key: key);
    
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      User _user;
      FirebaseAnalytics analytics;
      bool _error = false;
    
      void _handleLogin(User user) {
        // print("Handle Login");
        setState(() {
          _user = user;
        });
      }
    
      @override
      void initState() {
        super.initState();
    
        // if we opened the app through a notification, it will send us via this
        FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
          print('On Message Opened!');
          print(message);
        });
      }
    
      @override
      Widget build(BuildContext context) {
       }
    }
    
    
    
  • Abdol Hussain Mozaffari
    Abdol Hussain Mozaffari over 2 years
    Any way to handle the notification type manually for IOS? so it is not showing automatically?
  • pythonNovice
    pythonNovice over 2 years
    In that case, you would want to send your notification as a data type rather than notification. You can choose to manually show it via FlutterLocalNotifications
  • Abdol Hussain Mozaffari
    Abdol Hussain Mozaffari over 2 years
    yes, I know the data is not triggered automatically. but unfortunately, I can not change that from the server-side and want to handle it from the Flutter side.
  • Shailandra Rajput
    Shailandra Rajput over 2 years
    Not working in my case
  • Himank shah
    Himank shah about 2 years
    Did you found a solution to this issue, as i want to play a custom notification sound only when app is in background or terminated state and if i implement onBackgroundMessage i am getting two notifications one automatic and another manual