first commit
This commit is contained in:
92
lib/controllers/notifi/notification.dart
Normal file
92
lib/controllers/notifi/notification.dart
Normal file
@@ -0,0 +1,92 @@
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||
|
||||
|
||||
|
||||
class NotificationController extends GetxController {
|
||||
var notifications = <Map<String, String>>[].obs; // List of notifications
|
||||
late FlutterLocalNotificationsPlugin localNotifications;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
initNotifications();
|
||||
}
|
||||
|
||||
void initNotifications() async {
|
||||
localNotifications = FlutterLocalNotificationsPlugin();
|
||||
|
||||
const androidSettings = AndroidInitializationSettings('@mipmap/ic_launcher');
|
||||
const iosSettings = DarwinInitializationSettings(); // Updated for iOS
|
||||
await localNotifications.initialize(
|
||||
const InitializationSettings(android: androidSettings, iOS: iosSettings),
|
||||
);
|
||||
|
||||
// Listen for FCM foreground messages
|
||||
FirebaseMessaging.onMessage.listen((message) {
|
||||
showNotification(message);
|
||||
notifications.insert(0, {
|
||||
'title': message.notification?.title ?? '',
|
||||
'body': message.notification?.body ?? '',
|
||||
});
|
||||
update();
|
||||
});
|
||||
}
|
||||
|
||||
void showNotification(RemoteMessage message) async {
|
||||
const androidDetails = AndroidNotificationDetails(
|
||||
'channelId', 'channelName',
|
||||
importance: Importance.max,
|
||||
priority: Priority.high,
|
||||
);
|
||||
|
||||
const iosDetails = DarwinNotificationDetails(); // Updated for iOS
|
||||
const generalNotificationDetails =
|
||||
NotificationDetails(android: androidDetails, iOS: iosDetails);
|
||||
|
||||
await localNotifications.show(
|
||||
0,
|
||||
message.notification?.title ?? '',
|
||||
message.notification?.body ?? '',
|
||||
generalNotificationDetails,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
class NotificationPage extends StatelessWidget {
|
||||
final NotificationController controller = Get.put(NotificationController());
|
||||
|
||||
NotificationPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Notifications'),
|
||||
centerTitle: true,
|
||||
),
|
||||
body: Obx(() {
|
||||
if (controller.notifications.isEmpty) {
|
||||
return const Center(child: Text("No notifications yet"));
|
||||
}
|
||||
return ListView.builder(
|
||||
itemCount: controller.notifications.length,
|
||||
itemBuilder: (context, index) {
|
||||
final notification = controller.notifications[index];
|
||||
return ListTile(
|
||||
leading: const Icon(Icons.notifications),
|
||||
title: Text(notification['title'] ?? ''),
|
||||
subtitle: Text(notification['body'] ?? ''),
|
||||
);
|
||||
},
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
71
lib/controllers/notifi/schedule_notifi.dart
Normal file
71
lib/controllers/notifi/schedule_notifi.dart
Normal file
@@ -0,0 +1,71 @@
|
||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||
import 'package:timezone/data/latest_all.dart' as tz;
|
||||
import 'package:timezone/timezone.dart' as tz;
|
||||
|
||||
class NotificationService {
|
||||
static final NotificationService _instance = NotificationService._internal();
|
||||
factory NotificationService() => _instance;
|
||||
NotificationService._internal();
|
||||
|
||||
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
|
||||
FlutterLocalNotificationsPlugin();
|
||||
|
||||
Future<void> init() async {
|
||||
tz.initializeTimeZones(); // MUST do this
|
||||
final String timeZoneName = await tz.local.name;
|
||||
print("Device Timezone: $timeZoneName");
|
||||
|
||||
const AndroidInitializationSettings androidInit =
|
||||
AndroidInitializationSettings('@mipmap/ic_launcher');
|
||||
|
||||
const InitializationSettings initSettings =
|
||||
InitializationSettings(android: androidInit);
|
||||
|
||||
await flutterLocalNotificationsPlugin.initialize(
|
||||
initSettings,
|
||||
onDidReceiveNotificationResponse: (details) {
|
||||
print("Notification clicked!");
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> scheduleDailyNotification({
|
||||
required int id,
|
||||
required int hour,
|
||||
required int minute,
|
||||
String title = 'Check what’s new 👀',
|
||||
String body = 'Open the app to explore exciting updates!',
|
||||
}) async {
|
||||
final now = tz.TZDateTime.now(tz.local);
|
||||
|
||||
// Correctly calculate the next scheduled time
|
||||
tz.TZDateTime scheduledDate =
|
||||
tz.TZDateTime(tz.local, now.year, now.month, now.day, hour, minute);
|
||||
|
||||
if (scheduledDate.isBefore(now)) {
|
||||
// If time has already passed, schedule for tomorrow
|
||||
scheduledDate = scheduledDate.add(const Duration(days: 1));
|
||||
}
|
||||
|
||||
final androidDetails = AndroidNotificationDetails(
|
||||
'daily_channel',
|
||||
'Daily Notifications',
|
||||
importance: Importance.max,
|
||||
priority: Priority.max,
|
||||
);
|
||||
|
||||
final notificationDetails = NotificationDetails(android: androidDetails);
|
||||
|
||||
await flutterLocalNotificationsPlugin.zonedSchedule(
|
||||
id,
|
||||
title,
|
||||
body,
|
||||
scheduledDate,
|
||||
notificationDetails,
|
||||
androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle,
|
||||
matchDateTimeComponents: DateTimeComponents.time,
|
||||
);
|
||||
|
||||
print("Scheduled notification at $hour:$minute (Next trigger: $scheduledDate)");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user