Is there a way to implement the following functionality without using a remote server: In my app i can schedule reminders. Those trigger when the app is opened or running in the background but never when it is terminated. Are there any libs that can trigger scheduled notifications when the app is terminated or somehow schedule them to a OS-level of some sort? Or am I required to trigger them by a remote server like firebase?
Currently I am using the flutter_local_notifications package. My NotificationService looks like this:
import 'package:timezone/timezone.dart' as tz;
import '../db_models/reminder_model.dart';
class NotificationService {
final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
// Initialize the notification settings
Future<void> initNotifications() async {
final InitializationSettings initializationSettings = InitializationSettings(
android: AndroidInitializationSettings('@mipmap/ic_launcher'),
iOS: DarwinInitializationSettings(),
// Add other platform-specific settings if needed
);
await _flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse: _onDidReceiveNotificationResponse,
onDidReceiveBackgroundNotificationResponse: _onDidReceiveBackgroundNotificationResponse,
);
}
// Schedule a notification
Future<void> scheduleNotification(Reminder reminder) async {
// Convert triggerTime to a DateTime object
// Extract the current date
final currentDate = DateTime.now();
// Extract the hour and minute from the triggerTime
final timeParts = reminder.getTriggerTime().split(':');
final hour = int.parse(timeParts[0]);
final minute = int.parse(timeParts[1]);
// Combine them into a DateTime object
final scheduledTime = DateTime(currentDate.year, currentDate.month, currentDate.day, hour, minute);
//final DateTime scheduledTime = DateTime.parse(reminder.getTriggerTime());
final tz.TZDateTime tzScheduledTime = tz.TZDateTime.from(scheduledTime, tz.local);
print('TriggerTime: $tzScheduledTime');
// Define the notification details
var androidDetails = AndroidNotificationDetails(
'channel_id',
'channel_name',
channelDescription: 'channel_description',
importance: Importance.max,
priority: Priority.high,
);
var iosDetails = DarwinNotificationDetails();
var platformDetails = NotificationDetails(android: androidDetails, iOS: iosDetails);
// Schedule the notification
await _flutterLocalNotificationsPlugin.zonedSchedule(
reminder.getId(),
'Water Reminder',
'Time to drink water!',
tzScheduledTime,
platformDetails,
androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle,
uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime,
matchDateTimeComponents: DateTimeComponents.time, // To repeat daily at the same time
payload: "hey boss!!!!"
);
var pendingNotifications = await _flutterLocalNotificationsPlugin.pendingNotificationRequests();
for (var notification in pendingNotifications) {
print('Notification: id=${notification.id}, title=${notification.title}, body=${notification.body}, payload=${notification.payload}');
}
}
Future<void> triggerNotificationNow(int notificationId) async {
// Retrieve the details of the scheduled notification by its ID
// This step depends on how you store your scheduled notifications
var androidDetails = AndroidNotificationDetails(
'channel_id',
'channel_name',
channelDescription: 'channel_description',
importance: Importance.max,
priority: Priority.high,
);
var iosDetails = DarwinNotificationDetails();
var platformDetails = NotificationDetails(android: androidDetails, iOS: iosDetails);
// Schedule the notification to trigger immediately
await _flutterLocalNotificationsPlugin.zonedSchedule(
notificationId,
"Test",
"Wabec lol haha",
tz.TZDateTime.now(tz.local).add(Duration(seconds: 5)),
platformDetails, uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime
);
}
// Handle notification response when the app is running
void _onDidReceiveNotificationResponse(NotificationResponse response) {
// Handle the notification response
}
// Handle notification response when the app is in the background
}
void _onDidReceiveBackgroundNotificationResponse(
NotificationResponse response) {
print("Notification clicked with payload: ${response.payload}");
// Handle the background notification response
}
When I schedule a notification, it is triggered when the app is running in the foreground/background but never when it is terminated.
I tested this on the Android APIs: 28, 29 and 34 (And I am aware that from a certain API onward you need special permissions for exact scheduling)
You need to use Firebase push notifications or One Signal because ios dooes'nt support background fetch or that kind of thing. After that you can redirect coming notifications (from that services) your local solutions.