Files
workavia-mail-front/lib/features/push_notification/presentation/notification_service.dart
T
2022-12-02 16:13:47 +07:00

156 lines
5.1 KiB
Dart

import 'dart:async';
import 'dart:io';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:get/get.dart';
import 'package:model/firebase/firebase_dto.dart';
import 'package:rxdart/rxdart.dart';
import 'package:tmail_ui_user/features/push_notification/domain/usecases/save_firebase_cache_interactor.dart';
import 'package:tmail_ui_user/firebase_options.dart';
import 'notification_strings.dart';
final StreamController<NotificationResponse?> selectNotificationStream =
StreamController<NotificationResponse?>.broadcast();
@pragma('vm:entry-point')
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
await NotificationService.displayPushNotification(message);
}
@pragma('vm:entry-point')
void notificationTapBackground(NotificationResponse notificationResponse) {
//handle action
}
void onDidReceiveNotificationResponse(
NotificationResponse details,
) {
selectNotificationStream.add(details);
}
class NotificationService {
factory NotificationService() => _instance;
NotificationService._internal();
static final NotificationService _instance = NotificationService._internal();
static get _firebaseMessaging => FirebaseMessaging.instance;
static get _flutterLocalNotificationsPlugin =>
FlutterLocalNotificationsPlugin();
static final BehaviorSubject<NotificationResponse?>
_notificationActionStream =
BehaviorSubject<NotificationResponse?>.seeded(null);
static Stream<NotificationResponse?> get notificationActionStream =>
_notificationActionStream.stream;
static Stream<String> get onTokenRefresh => _firebaseMessaging.onTokenRefresh;
static bool _isFlutterLocalNotificationsInitialized = false;
static Future<void> initializeNotificationService(
Function(NotificationResponse)? onDidReceiveNotificationResponse,
) async {
if (_isFlutterLocalNotificationsInitialized) return;
final _saveFirebaseCacheInteractor = Get.find<SaveFirebaseCacheInteractor>();
final token = await _firebaseMessaging.getToken();
_saveFirebaseCacheInteractor.execute(FirebaseDto(token));
await _initFirebaseMessaging();
await _flutterLocalNotificationsPlugin.initialize(
InitializationSettings(
android: androidInitializationSettings,
iOS: iosInitializationSettings,
),
onDidReceiveNotificationResponse: onDidReceiveNotificationResponse,
onDidReceiveBackgroundNotificationResponse: notificationTapBackground,
);
await _requestPermissions();
await _createNotificationChannels();
_listenNotificationActionStream();
_isFlutterLocalNotificationsInitialized = true;
}
static Future<void> displayPushNotification(
RemoteMessage notification,
) async {
try {
await _flutterLocalNotificationsPlugin.show(
createUniqueId,
channelName,
notification.data.toString(),
pushNotificationDetails,
);
} catch (e) {
debugPrint(e.toString());
}
}
static Future<void> cancelAllNotifications() async {
await _flutterLocalNotificationsPlugin.cancelAll();
}
static Future<void> _initFirebaseMessaging() async {
FirebaseMessaging.onMessage.listen(_handleIncomingForegroundNotification);
FirebaseMessaging.onMessageOpenedApp.listen(_handleOpenedAppNotification);
}
static Future<void> _handleIncomingForegroundNotification(
RemoteMessage remoteMessage,
) async {
await displayPushNotification(remoteMessage);
}
static void _handleOpenedAppNotification(RemoteMessage remoteMessage) {}
static Future<void> _requestPermissions() async {
if (Platform.isAndroid) {
await _flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.requestPermission();
} else {
await _flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
IOSFlutterLocalNotificationsPlugin>()
?.requestPermissions(
alert: true,
badge: true,
sound: true,
);
}
}
static Future<void> _listenNotificationActionStream() async {
selectNotificationStream.stream
.listen((event) => event)
.onData((data) async {
_notificationActionStream.add(data);
switch (data?.notificationResponseType) {
case NotificationResponseType.selectedNotification:
break;
case NotificationResponseType.selectedNotificationAction:
break;
default:
}
});
}
static Future<void> _createNotificationChannels() async {
await _flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(androidChannel);
}
static Future<void> deleteToken() async => _firebaseMessaging.deleteToken();
}
int get createUniqueId =>
DateTime.now().millisecondsSinceEpoch.remainder(100000);