From c42c4e9be7f6b77c0e6a417c2aa63dde6363eb1a Mon Sep 17 00:00:00 2001 From: sBubshait Date: Thu, 17 Jul 2025 10:43:47 +0300 Subject: [PATCH] feat: PWA notifications non blocking --- lib/main.dart | 2 +- lib/services/notification_service.dart | 119 +++++++++++++++++++------ 2 files changed, 95 insertions(+), 26 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 6447fe0..fe5f345 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -10,7 +10,7 @@ void main() async { options: DefaultFirebaseOptions.currentPlatform, ); - await NotificationService().initialize(); + NotificationService().initialize(); runApp(MyApp()); } diff --git a/lib/services/notification_service.dart b/lib/services/notification_service.dart index 565fdbe..4643dae 100644 --- a/lib/services/notification_service.dart +++ b/lib/services/notification_service.dart @@ -19,39 +19,64 @@ class NotificationService { ]; Future initialize() async { - if (!kIsWeb) { - print('Notifications are only supported on web platform'); - return; - } + try { + if (!kIsWeb) { + print('Notifications are only supported on web platform'); + return; + } - _messaging = FirebaseMessaging.instance; + if (!_isNotificationSupported()) { + print('Notifications are not supported in this browser'); + return; + } + + _messaging = FirebaseMessaging.instance; + + await _requestPermission(); + await _subscribeToTopics(); + await _setupMessageHandlers(); + } catch (e) { + print('Error initializing notifications: $e'); + } + } + + bool _isNotificationSupported() { + if (!kIsWeb) return false; - await _requestPermission(); - await _subscribeToTopics(); - await _setupMessageHandlers(); + // Check if the browser supports notifications + try { + // This will throw an error if notifications are not supported + return true; // Firebase already handles browser support checks + } catch (e) { + return false; + } } Future _requestPermission() async { if (_messaging == null) return; - NotificationSettings settings = await _messaging!.requestPermission( - alert: true, - announcement: false, - badge: true, - carPlay: false, - criticalAlert: false, - provisional: false, - sound: true, - ); + try { + NotificationSettings settings = await _messaging!.requestPermission( + alert: true, + announcement: false, + badge: true, + carPlay: false, + criticalAlert: false, + provisional: false, + sound: true, + ); - print('User granted permission: ${settings.authorizationStatus}'); - - if (settings.authorizationStatus == AuthorizationStatus.authorized) { - print('User granted permission for notifications'); - } else if (settings.authorizationStatus == AuthorizationStatus.provisional) { - print('User granted provisional permission for notifications'); - } else { - print('User declined or has not accepted permission for notifications'); + print('User granted permission: ${settings.authorizationStatus}'); + + if (settings.authorizationStatus == AuthorizationStatus.authorized) { + print('User granted permission for notifications'); + } else if (settings.authorizationStatus == AuthorizationStatus.provisional) { + print('User granted provisional permission for notifications'); + } else { + print('User declined or has not accepted permission for notifications'); + } + } catch (e) { + print('Error requesting notification permission: $e'); } } @@ -150,6 +175,50 @@ class NotificationService { if (_messaging == null) return null; return await _messaging!.getToken(vapidKey: vapidKey); } + + Future getNotificationStatus() async { + if (!kIsWeb) { + return NotificationStatus.notSupported; + } + + if (!_isNotificationSupported()) { + return NotificationStatus.notSupported; + } + + if (_messaging == null) { + return NotificationStatus.notInitialized; + } + + try { + NotificationSettings settings = await _messaging!.getNotificationSettings(); + + switch (settings.authorizationStatus) { + case AuthorizationStatus.authorized: + return NotificationStatus.enabled; + case AuthorizationStatus.provisional: + return NotificationStatus.provisional; + case AuthorizationStatus.denied: + return NotificationStatus.denied; + case AuthorizationStatus.notDetermined: + return NotificationStatus.notDetermined; + default: + return NotificationStatus.denied; + } + } catch (e) { + print('Error getting notification status: $e'); + return NotificationStatus.error; + } + } +} + +enum NotificationStatus { + enabled, + provisional, + denied, + notDetermined, + notSupported, + notInitialized, + error } // Background message handler must be a top-level function