i have an event attached to notification whose value i want to change when notification happens in flutter using flutter_local_notification
I have tried everything i can think of. My main problem is how to pass WidgetRef around
below is my code
main.dart
import 'package:event_notification_app/components/routes/routes.dart';
import 'package:event_notification_app/components/theme/theme.dart';
import 'package:event_notification_app/features/splash_screen/views/splash_screen.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'components/services/notification_services.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
NotificationService notificationService = NotificationService(ref);
await Hive.initFlutter();
runApp(
const ProviderScope(
child: MyApp(),
),
);
}
class MyApp extends ConsumerWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: AppTheme.lightThemeMode,
darkTheme: AppTheme.darkThemeMode,
initialRoute: SplashScreen.routeName,
routes: routes,
);
}
}
notification_services.dart
import 'package:event_notification_app/components/constants/update_notification_state.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:timezone/timezone.dart' as tz;
import 'package:timezone/data/latest.dart' as tz;
final notificationServiceProvider =
Provider<NotificationService>((ref) => NotificationService(ref));
Future<void> _handleBackgroundNotification(
NotificationResponse response, Ref ref) async {
try {
UpdateNotificationState updateNotificationState =
UpdateNotificationState(ref);
updateNotificationState.updateEventStateToNotified(response.payload!);
} catch (e) {
debugPrint("Error handling notification: $e");
}
}
Future<void> _handleNotification(NotificationResponse response, Ref ref) async {
try {
UpdateNotificationState updateNotificationState =
UpdateNotificationState(ref);
updateNotificationState.updateEventStateToNotified(response.payload!);
} catch (e) {
debugPrint("Error handling notification: $e");
}
}
class NotificationService {
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
NotificationService(Ref ref) {
_initializeNotification(ref);
}
Future<void> _initializeNotification(Ref ref) async {
tz.initializeTimeZones();
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('@mipmap/ic_launcher');
const InitializationSettings initializationSettings =
InitializationSettings(android: initializationSettingsAndroid);
try {
await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse: (response) =>
_handleNotification(response, ref),
onDidReceiveBackgroundNotificationResponse: (response) =>
_handleBackgroundNotification(response, ref),
);
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.requestNotificationsPermission();
} catch (e) {
debugPrint(e.toString());
}
}
Future<void> scheduleNotification(int id, String title, String body,
DateTime scheduleTime, String payload) async {
try {
await flutterLocalNotificationsPlugin.zonedSchedule(
id,
title,
body,
tz.TZDateTime.from(scheduleTime, tz.local),
const NotificationDetails(
android: AndroidNotificationDetails(
'event_channel',
'Event Notifications',
channelDescription: 'This channel is used for event Notification',
importance: Importance.max,
enableVibration: true,
playSound: true,
sound: RawResourceAndroidNotificationSound('new_event_female'),
),
),
androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime,
payload: payload,
);
} catch (e) {
debugPrint(e.toString());
}
}
}
update_state.dart
import 'package:event_notification_app/features/home_screen/model/events.dart';
import 'package:event_notification_app/features/home_screen/view_model/event_notifiers.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class UpdateNotificationState {
final Ref ref;
late EventsNotifier eventNotifier = ref.read(eventsNotifierProvider.notifier);
late final eventState = ref.read(eventsNotifierProvider);
UpdateNotificationState(this.ref);
Events? _getEvent(String payload) {
final eventList = eventState;
if (eventList.isNotEmpty) {
for (final event in eventList) {
if (event.eventName == payload) {
return event;
}
}
}
return null;
}
void updateEventStateToNotified(String payload) {
try {
final event = _getEvent(payload);
if (event != null) {
eventNotifier.onNotificationFired(event);
} else {
debugPrint("Event not found for notification payload: $payload");
}
} catch (e) {
debugPrint(e.toString());
}
}
}
class Events {
@HiveField(0)
String eventName;
@HiveField(1)
DateTime dateTime;
@HiveField(2)
EventNotificationState eventNotificationState;
Events({
required this.eventName,
required this.dateTime,
this.eventNotificationState = EventNotificationState.created,
});
}
@HiveType(typeId: 1)
enum EventNotificationState {
@HiveField(0)
created,
@HiveField(1)
notified,
@HiveField(2)
spoken
}
this eventNotificationState is what I am trying to change.