5import 'package:connect/core/router/routes.dart';
6import 'package:firebase_core/firebase_core.dart';
7import 'package:firebase_messaging/firebase_messaging.dart';
8import 'package:flutter_local_notifications/flutter_local_notifications.dart';
9import 'package:cloud_firestore/cloud_firestore.dart';
10import 'package:go_router/go_router.dart';
11import 'package:connect/core/router/router.dart' show rootNavigatorKey;
12import 'package:shared_preferences/shared_preferences.dart';
13import '../../features/authentication/domain/entities/session_entity.dart';
14import 'package:flutter_bloc/flutter_bloc.dart';
15import '../../features/collections/presentation/logic/collection_requests_history_bloc/collection_requests_history_bloc.dart';
16import '../../features/authentication/presentation/logic/authentication_bloc/authentication_bloc.dart';
19Future<
void> firebaseMessagingBackgroundHandler(RemoteMessage
message) async {
20 await Firebase.initializeApp();
21 await SharedPreferences.getInstance().then((prefs) {
22 if (
message.data[
'type'] ==
'business') {
23 prefs.setString(
'pending_notification', json.encode(
message.data));
40 FlutterLocalNotificationsPlugin();
46 Future<void>
init() async {
60 if (
settings.authorizationStatus == AuthorizationStatus.authorized) {
64 FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
70 final prefs = await SharedPreferences.getInstance();
71 final pendingNotification = prefs.getString(
'pending_notification');
72 final wasClicked = prefs.getBool(
'notification_clicked') ??
false;
74 if (pendingNotification != null && wasClicked) {
78 if (initialMessage != null) {
79 await prefs.setString(
80 'pending_notification',
81 json.encode(initialMessage.data),
83 await prefs.setBool(
'notification_clicked',
true);
98 Future.delayed(
const Duration(milliseconds: 500), () async {
100 final prefs = await SharedPreferences.getInstance();
101 final pendingNotification = prefs.getString(
'pending_notification');
102 if (pendingNotification != null) {
103 final data = json.decode(pendingNotification);
106 await prefs.remove(
'pending_notification');
107 await prefs.remove(
'notification_clicked');
114 const AndroidInitializationSettings initializationSettingsAndroid =
115 AndroidInitializationSettings(
'@mipmap/ic_launcher');
117 final DarwinInitializationSettings initializationSettingsIOS =
118 DarwinInitializationSettings(
119 requestSoundPermission:
true,
120 requestBadgePermission:
true,
121 requestAlertPermission:
true,
124 final InitializationSettings initializationSettings =
125 InitializationSettings(
126 android: initializationSettingsAndroid,
127 iOS: initializationSettingsIOS,
131 initializationSettings,
140 final deviceTokenDoc = {
142 'platform': Platform.operatingSystem,
143 'loginTimestamp': FieldValue.serverTimestamp(),
147 await FirebaseFirestore.instance
150 .collection(
'deviceTokens')
152 .set(deviceTokenDoc, SetOptions(merge:
true));
159 await FirebaseFirestore.instance
162 .collection(
'deviceTokens')
164 .update({
'isActive':
false});
168 if (
message.notification != null) {
171 body:
message.notification!.body ??
'',
178 required String
title,
179 required String body,
180 required Map<String, dynamic> payload,
182 const AndroidNotificationDetails androidPlatformChannelSpecifics =
183 AndroidNotificationDetails(
184 'high_importance_channel',
185 'High Importance Notifications',
186 importance: Importance.max,
187 priority: Priority.high,
190 const DarwinNotificationDetails iOSPlatformChannelSpecifics =
191 DarwinNotificationDetails(
197 const NotificationDetails platformChannelSpecifics = NotificationDetails(
198 android: androidPlatformChannelSpecifics,
199 iOS: iOSPlatformChannelSpecifics,
206 platformChannelSpecifics,
207 payload: json.encode(payload),
212 await SharedPreferences.getInstance().then((prefs) {
213 prefs.setBool(
'notification_clicked',
true);
220 if (notificationResponse.payload != null) {
221 final payload =
_parsePayload(notificationResponse.payload!);
228 return json.decode(payloadString);
235 final String? notificationType = data[
'type'] as String?;
236 if (notificationType ==
'business') {
238 final authState = context.read<AuthenticationBloc>().state;
239 if (authState is AuthenticatedState) {
240 final String?
partnerId = authState.session.partnerId;
242 context.read<CollectionRequestsHistoryBloc>().add(
247 GoRouter.of(context).push(
Routes.transactionHistory.route);
final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin
void _navigateBasedOnNotification(Map< String, dynamic > data)
Future< void > removeDeviceToken(String token) async
Future< void > _initLocalNotifications() async
Future< void > _showLocalNotification({ required String title, required String body, required Map< String, dynamic > payload, }) async
bool _hasPendingNavigation
static final NotificationService _instance
final FirebaseMessaging _firebaseMessaging
Future< void > _handleForegroundMessage(RemoteMessage message) async
void _onNotificationTap(NotificationResponse notificationResponse)
Future< void > _checkPendingNotification() async
Future< void > init() async
SessionEntity _currentSession
factory NotificationService()
Future< void > _saveDeviceToken(String token) async
void _handleNotificationTap(RemoteMessage message) async
void updateSession(SessionEntity? session)
Map< String, dynamic > _parsePayload(String payloadString)
Future< void > setupAfterAuthentication(SessionEntity session) async
const LoadOnGoingCollectionRequestsEvent({required this.partnerId})
pragma('vm:entry-point') Future< void > firebaseMessagingBackgroundHandler(RemoteMessage message) async