I’m building an app with Flutter for Android and iOS that every day should check for new data and send a notification to the user. To achieve it, I’m using workmanager, to schedule the job, and flutter_local_notifications to show the notification.
When the job runs, no notification is shown and no exception get caught.
However, if I try to display a notification as per flutter_local_notifications docs, i.e. without workmanager, it works correctly.
This is a MRE of my main.dart that shows how I’m scheduling the job and showing the notification:
import 'dart:io';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:intl/intl.dart';
import 'package:timezone/data/latest_all.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
import 'package:workmanager/workmanager.dart';
import 'package:intl/date_symbol_data_local.dart';
final localNotificationPlugin = FlutterLocalNotificationsPlugin();
bool _initialized = false;
void main() async {
await initialize();
Workmanager().initialize(callbackDispatcher);
runApp(App());
}
@pragma('vm:entry-point')
Future initialize() async {
WidgetsFlutterBinding.ensureInitialized();
await initializeDateFormatting(Platform.localeName, null);
await initLocalNotificationPlugin();
tz.initializeTimeZones();
tz.setLocalLocation(tz.getLocation(DateTime.now().timeZoneName));
}
Future initLocalNotificationPlugin() async {
if (_initialized) {
return;
}
_initialized = true;
const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('@mipmap/ic_launcher');
final DarwinInitializationSettings initializationSettingsDarwin = DarwinInitializationSettings();
final InitializationSettings initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsDarwin
);
await localNotificationPlugin.initialize(initializationSettings);
}
@pragma('vm:entry-point')
void callbackDispatcher() {
Workmanager().executeTask((task, inputData) async {
print('callbackDispatcher');
try {
await initialize();
} catch (e) {
print("Exception on callbackDispatcher");
print(e);
}
switch (task) {
case "fetchAndShow":
await sendNotification();
break;
default:
// Handle unknown task types
break;
}
return Future.value(true);
});
}
@pragma('vm:entry-point')
Future sendNotification() async {
try {
await localNotificationPlugin.show(
0,
"Notification Title",
"Notification Body",
NotificationDetails(
android: AndroidNotificationDetails("channel_id", "channel_name")
)
);
} catch (e) {
print('Exception on sendNotification');
print(e);
}
}
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
Workmanager().registerPeriodicTask('dataSync', 'fetchAndShow', frequency: Duration(days: 1));
// Build logic
}
}
I’m using:
- flutter:
^3.9.2 - intl:
^0.20.2 - flutter_local_notifications:
^19.5.0 - timezone:
^0.10.1 - workmanager:
^0.9.0+3