Home > database >  How can I run background code when a notification is executed with Flutter?
How can I run background code when a notification is executed with Flutter?

Time:12-28

I am using flutter_local_notification and workmanager plugins in order to run some background code when a notification is generated (only Android). This is how flutter_local_notification is initialised:

final StreamController<ReceivedNotification> didReceiveLocalNotificationSubject = StreamController<ReceivedNotification>.broadcast();

Future<void> init() async {
    await _configureLocalTimeZone();

    notificationAppLaunchDetails = await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails();
    if (notificationAppLaunchDetails!.didNotificationLaunchApp) {
      selectedNotificationPayload = notificationAppLaunchDetails!.notificationResponse?.payload;
    }

    const AndroidInitializationSettings initializationSettingsAndroid =
    AndroidInitializationSettings('@mipmap/ic_launcher');

    InitializationSettings initializationSettings = const InitializationSettings(
      android: initializationSettingsAndroid,
    );
    await flutterLocalNotificationsPlugin.initialize(
        initializationSettings,
        onDidReceiveNotificationResponse:
            (NotificationResponse notificationResponse) {
          switch (notificationResponse.notificationResponseType) {
            case NotificationResponseType.selectedNotification:
            case NotificationResponseType.selectedNotificationAction:
              // if (notificationResponse.actionId == navigationActionId) {
                selectNotificationSubject.add(notificationResponse.payload);
                selectedNotificationPayload = notificationResponse.payload;
              // }
                didReceiveLocalNotificationSubject.add(
                  ReceivedNotification(
                    id: notificationResponse.id!,
                    title: notificationResponse.actionId,
                    body: 'stuff',
                    payload: notificationResponse.payload,
                  ),
                );
              break;
          }
      },
      // onDidReceiveBackgroundNotificationResponse: notificationTapBackground,
    );

    _notificationsEnabled = await _isAndroidPermissionGranted();
    _notificationsEnabled = await _requestPermissions();
    _configureDidReceiveLocalNotificationSubject();
  }

and this is the code that gets executed with Workmanager:

void _configureDidReceiveLocalNotificationSubject() {
    didReceiveLocalNotificationSubject.stream
        .listen((ReceivedNotification receivedNotification) async {
          var title = receivedNotification.title ?? 'UNKNOWN';
          Workmanager().registerOneOffTask(
            "my.simpleTask",
            "my.simpleTask",
            inputData: <String, dynamic>{
              'string': title,
            },
          );
        });
  }

Currently I have two problems with that code:

  • the Workmanager's task is run only when the user tap the notification
  • the Workmanager's task won't be executed if the app is terminated by the user first, even if the notification is generated (and tapped)

How can I make the Workmanager's task to be executed as soon as the notification is generated (without the user tapping) with the application terminated or not?

CodePudding user response:

i assume you are scheduled local notification and execute some function in there.

TL:DR

  • first: scheduled local notification not able to execute function in background

eg:

int randomInt = Random().nextInt();
await flutterLocalNotificationsPlugin.zonedSchedule(
    0,
    'scheduled notif with int $randomInt',
     ....

when you are registed this notif, you will get randomInt, and then on the notification it will show the int that you get first time its scheduled. which means, its only show notification,Random().nextInt is not executed.

  • secondly,
void _configureDidReceiveLocalNotificationSubject() {
    didReceiveLocalNotificationSubject.stream

stream function will be terminated too after the apps is killed. except you are bring it into foreground. the stream will keep listening any changes.


How can I make the Workmanager's task to be executed as soon as the notification is generated

I think you are missed on this part. the correct way is: Register Workmanager and then inside the callback function, you can generated local notification.

  • register your WM in your initState
Workmanager().registerOneOffTask(
  "task-identifier",
  simpleTaskKey,
  initialDelay: Duration(minutes: 30), // you can use this delay for scheduling
);

then in the callback funtion generete local notificaiton

@pragma('vm:entry-point')
void callbackDispatcher() {
  Workmanager().executeTask((task, inputData) {
   // you function execute here
   // eg: final tempInt = Random.nextInt();
   // then we can use the tempInt 

    show local notification function here
    return Future.value(true);
  });
}
  • Related