import 'dart:async'; import 'package:core/utils/app_logger.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:tmail_ui_user/features/push_notification/presentation/controller/fcm_message_controller.dart'; import 'package:tmail_ui_user/features/push_notification/presentation/notification/local_notification_manager.dart'; class FcmService { static const int durationMessageComing = 2000; static const int durationRefreshToken = 2000; late StreamController foregroundMessageStreamController; Stream get foregroundMessageStream => foregroundMessageStreamController.stream; late StreamController backgroundMessageStreamController; Stream get backgroundMessageStream => backgroundMessageStreamController.stream; late StreamController fcmTokenStreamController; Stream get fcmTokenStream => fcmTokenStreamController.stream; FcmService._internal() { foregroundMessageStreamController = StreamController.broadcast(); backgroundMessageStreamController = StreamController.broadcast(); fcmTokenStreamController = StreamController.broadcast(); } static final FcmService _instance = FcmService._internal(); static FcmService get instance => _instance; void handleFirebaseForegroundMessage(RemoteMessage newRemoteMessage) { log('FcmService::handleFirebaseForegroundMessage():message: ${newRemoteMessage.data}'); if (!foregroundMessageStreamController.isClosed) { foregroundMessageStreamController.add(newRemoteMessage); } } void handleFirebaseBackgroundMessage(RemoteMessage newRemoteMessage) { FcmMessageController.instance.initialize(); if (!backgroundMessageStreamController.isClosed) { backgroundMessageStreamController.add(newRemoteMessage); } } void handleFirebaseMessageOpenedApp(RemoteMessage newRemoteMessage) async { log("FcmService::handleFirebaseMessageOpenedApp:"); await LocalNotificationManager.instance.removeNotificationBadgeForIOS(); } void handleGetToken(String? currentToken) async { log('FcmService::handleGetToken():currentToken: $currentToken'); if (fcmTokenStreamController.isClosed) { log('FcmService::handleGetToken():fcmTokenStreamController: isClosed'); fcmTokenStreamController = StreamController.broadcast(); await FcmMessageController.instance.listenTokenStream(); } if (!fcmTokenStreamController.isClosed) { fcmTokenStreamController.add(currentToken); } } void handleRefreshToken(String? newToken) async { log('FcmService::handleRefreshToken():newToken: $newToken'); if (fcmTokenStreamController.isClosed) { log('FcmService::handleRefreshToken():fcmTokenStreamController: isClosed'); fcmTokenStreamController = StreamController.broadcast(); await FcmMessageController.instance.listenTokenStream(); } if (!fcmTokenStreamController.isClosed) { fcmTokenStreamController.add(newToken); } } Future recreateStreamController() async { if (foregroundMessageStreamController.isClosed) { foregroundMessageStreamController = StreamController.broadcast(); await FcmMessageController.instance.listenForegroundMessageStream(); } if (backgroundMessageStreamController.isClosed) { backgroundMessageStreamController = StreamController.broadcast(); await FcmMessageController.instance.listenBackgroundMessageStream(); } if (fcmTokenStreamController.isClosed) { fcmTokenStreamController = StreamController.broadcast(); await FcmMessageController.instance.listenTokenStream(); } return Future.value(); } void closeStream() { foregroundMessageStreamController.close(); backgroundMessageStreamController.close(); fcmTokenStreamController.close(); } }