Bilal Rabbi
Bilal Rabbi

Reputation: 1850

Hide flutter local notification on foreground

I want to hide notification when app is in foreground but IOS is showing notification even in foreground. Normally FCM notification are not shown when app is in foreground. Here is my code

await flutterLocalNotificationsPlugin
        .resolvePlatformSpecificImplementation<
            AndroidFlutterLocalNotificationsPlugin>()
        ?.createNotificationChannel(channel);

    AndroidInitializationSettings androidInitializationSettings =
        AndroidInitializationSettings('@mipmap/ic_launcher');
    IOSInitializationSettings iosInitializationSettings =
        IOSInitializationSettings();

    InitializationSettings initializationSettings = InitializationSettings(
        android: androidInitializationSettings, iOS: iosInitializationSettings);

    flutterLocalNotificationsPlugin.initialize(initializationSettings,
        onSelectNotification: onSelectNotification);

    final bool? result = await flutterLocalNotificationsPlugin
        .resolvePlatformSpecificImplementation<
            IOSFlutterLocalNotificationsPlugin>()
        ?.requestPermissions(
          alert: true,
          badge: true,
          sound: true,
        );

Upvotes: 1

Views: 4207

Answers (4)

Walulya francis
Walulya francis

Reputation: 573

Currently it's against google play policy to run a foreground service without notification because the user needs to know which app is consuming memory on the device. But lets say you are using https://pub.dev/packages/flutter_background_service for services and https://pub.dev/packages/awesome_notifications for notification. you can trick the service in removing the sticky notification but it will show at the start of service. i only tested this trick on android 10 First initialize service with the same channel key as Awesome_notifications

Future<void> main() async {
  await initializeService();
  runApp(const MyApp());
}

Future<void> initializeService() async {
  final service = FlutterBackgroundService();
  const notificationChannelId = 'com_example_channel_id';
  // initialize awesome notifications
  await NotificationController.initializeLocalNotifications(notificationChannelId);
  ////
  const notificationId = 888;
  await service.configure(
    androidConfiguration: AndroidConfiguration(
      onStart: onStart,
      autoStart: true,
      autoStartOnBoot: true,
      isForegroundMode: true,
      initialNotificationTitle: "",
      initialNotificationContent: "",
      notificationChannelId: notificationChannelId,
      foregroundServiceNotificationId: notificationId,
    ),
    iosConfiguration: IosConfiguration(
      onForeground: onStart,
    ),
  );
}

In the onStart method remove the channel and re-initialize the notification again

   @pragma('vm:entry-point')
    Future<void> onStart(ServiceInstance service) async {
      // Only available for flutter 3.0.0 and later
      DartPluginRegistrant.ensureInitialized();
      const notificationChannelId = 'com_example_channel_id';
      // remove channel 
      await AwesomeNotifications()
          .removeChannel(notificationChannelId);
      await 
    NotificationController.initializeLocalNotifications(notificationChannelId);
   /// your code goes here 
}
 

In the NotificationController class add this code

class NotificationController {
     static Future<void> initializeLocalNotifications(String notificationChannelId) async {
    // init notification channel
        await AwesomeNotifications().initialize(
          "resource://drawable/ic_bg_service_small",
          [
            NotificationChannel(
              channelKey: notificationChannelId,
              channelName: 'My notification Updates',
              channelDescription: 'My notification Updates',
              playSound: true,
              onlyAlertOnce: true,
              importance: NotificationImportance.High,
              defaultPrivacy: NotificationPrivacy.Private,
              defaultColor: Colors.blue,
              ledColor: Colors.blue,
              icon: "resource://drawable/ic_bg_service_small",
            )
          ],
          debug: true,
        );
    
        // Get initial notification action is optional
        initialAction = await AwesomeNotifications()
            .getInitialNotificationAction(removeFromActionEvents: false);
      }
    }
}

I haven't tried this trick with FlutterLocalNotificationsPlugin and i hope google hasn't patched this yet, you must first confirm.

Note: Since the service will make a notification but for a short time after it is started, you can use different notification initialization setting like removing sound, changing notification priority on the first Disclaimer This might not work in some cases. Awesome notification must recreate the removed channel before you make any notification or else the app will crush

Upvotes: 0

gdelataillade
gdelataillade

Reputation: 36

I have a solution for iOS.

When you initialize IOSInitializationSettings you have those params:

presentAlert: Display an alert when the notification is triggered while app is in the foreground. presentSound: Play a sound when the notification is triggered while app is in the foreground. presentBadge: Apply the badge value when the notification is triggered while app is in the foreground.

So if you set those params to false, notifications should be shown on background and hidden on foreground.

Upvotes: 1

Bilal Rabbi
Bilal Rabbi

Reputation: 1850

Just need to add this line

await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
    alert: false,
    badge: false,
    sound: false,
  );

Upvotes: 2

Etornam
Etornam

Reputation: 493

If you don't want to see the notifications in foreground, then add your code to only the onBackgroundMessage handler.

Upvotes: -1

Related Questions