feat: PWA notifications non blocking

This commit is contained in:
sBubshait 2025-07-17 10:43:47 +03:00
parent b2a4ffeb9b
commit c42c4e9be7
2 changed files with 95 additions and 26 deletions

View File

@ -10,7 +10,7 @@ void main() async {
options: DefaultFirebaseOptions.currentPlatform, options: DefaultFirebaseOptions.currentPlatform,
); );
await NotificationService().initialize(); NotificationService().initialize();
runApp(MyApp()); runApp(MyApp());
} }

View File

@ -19,39 +19,64 @@ class NotificationService {
]; ];
Future<void> initialize() async { Future<void> initialize() async {
if (!kIsWeb) { try {
print('Notifications are only supported on web platform'); if (!kIsWeb) {
return; print('Notifications are only supported on web platform');
return;
}
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');
} }
}
_messaging = FirebaseMessaging.instance; bool _isNotificationSupported() {
if (!kIsWeb) return false;
await _requestPermission(); // Check if the browser supports notifications
await _subscribeToTopics(); try {
await _setupMessageHandlers(); // This will throw an error if notifications are not supported
return true; // Firebase already handles browser support checks
} catch (e) {
return false;
}
} }
Future<void> _requestPermission() async { Future<void> _requestPermission() async {
if (_messaging == null) return; if (_messaging == null) return;
NotificationSettings settings = await _messaging!.requestPermission( try {
alert: true, NotificationSettings settings = await _messaging!.requestPermission(
announcement: false, alert: true,
badge: true, announcement: false,
carPlay: false, badge: true,
criticalAlert: false, carPlay: false,
provisional: false, criticalAlert: false,
sound: true, provisional: false,
); sound: true,
);
print('User granted permission: ${settings.authorizationStatus}'); print('User granted permission: ${settings.authorizationStatus}');
if (settings.authorizationStatus == AuthorizationStatus.authorized) { if (settings.authorizationStatus == AuthorizationStatus.authorized) {
print('User granted permission for notifications'); print('User granted permission for notifications');
} else if (settings.authorizationStatus == AuthorizationStatus.provisional) { } else if (settings.authorizationStatus == AuthorizationStatus.provisional) {
print('User granted provisional permission for notifications'); print('User granted provisional permission for notifications');
} else { } else {
print('User declined or has not accepted permission for notifications'); 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; if (_messaging == null) return null;
return await _messaging!.getToken(vapidKey: vapidKey); return await _messaging!.getToken(vapidKey: vapidKey);
} }
Future<NotificationStatus> 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 // Background message handler must be a top-level function