diff --git a/ios/Podfile b/ios/Podfile index 8f4bfd94..fa109b46 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -42,4 +42,12 @@ post_install do |installer| end end + + awesome_pod_file = File.expand_path(File.join('plugins', 'awesome_notifications', 'ios', 'Scripts', 'AwesomePodFile'), '.symlinks') + require awesome_pod_file + update_awesome_pod_build_settings(installer) end + + awesome_pod_file = File.expand_path(File.join('plugins', 'awesome_notifications', 'ios', 'Scripts', 'AwesomePodFile'), '.symlinks') + require awesome_pod_file + update_awesome_main_target_settings('Runner', File.dirname(File.realpath(__FILE__)), flutter_root) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index d266b4e3..e75cf60e 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,4 +1,7 @@ PODS: + - awesome_notifications (0.9.3): + - Flutter + - IosAwnCore (~> 0.9.3) - connectivity_plus (0.0.1): - Flutter - FlutterMacOS @@ -133,8 +136,6 @@ PODS: - flutter_inappwebview_ios/Core (0.0.1): - Flutter - OrderedSet (~> 5.0) - - flutter_local_notifications (0.0.1): - - Flutter - flutter_secure_storage (6.0.0): - Flutter - GoogleAppMeasurement (10.27.0): @@ -191,6 +192,7 @@ PODS: - GoogleUtilities/Privacy - image_picker_ios (0.0.1): - Flutter + - IosAwnCore (0.9.3) - local_auth_darwin (0.0.1): - Flutter - FlutterMacOS @@ -229,6 +231,7 @@ PODS: - Flutter DEPENDENCIES: + - awesome_notifications (from `.symlinks/plugins/awesome_notifications/ios`) - connectivity_plus (from `.symlinks/plugins/connectivity_plus/darwin`) - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - file_picker (from `.symlinks/plugins/file_picker/ios`) @@ -238,7 +241,6 @@ DEPENDENCIES: - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) - Flutter (from `Flutter`) - flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`) - - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`) - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) - local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`) @@ -268,6 +270,7 @@ SPEC REPOS: - GoogleAppMeasurement - GoogleDataTransport - GoogleUtilities + - IosAwnCore - nanopb - OrderedSet - PromisesObjC @@ -276,6 +279,8 @@ SPEC REPOS: - SwiftyGif EXTERNAL SOURCES: + awesome_notifications: + :path: ".symlinks/plugins/awesome_notifications/ios" connectivity_plus: :path: ".symlinks/plugins/connectivity_plus/darwin" device_info_plus: @@ -294,8 +299,6 @@ EXTERNAL SOURCES: :path: Flutter flutter_inappwebview_ios: :path: ".symlinks/plugins/flutter_inappwebview_ios/ios" - flutter_local_notifications: - :path: ".symlinks/plugins/flutter_local_notifications/ios" flutter_secure_storage: :path: ".symlinks/plugins/flutter_secure_storage/ios" image_picker_ios: @@ -320,6 +323,7 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/webview_flutter_wkwebview/ios" SPEC CHECKSUMS: + awesome_notifications: 66d28ab7174ca2823b04d275cb043e0a4a3eb9cf connectivity_plus: ddd7f30999e1faaef5967c23d5b6d503d10434db device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c @@ -341,12 +345,12 @@ SPEC CHECKSUMS: FirebaseSessions: dbd14adac65ce996228652c1fc3a3f576bdf3ecc Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 flutter_inappwebview_ios: 97215cf7d4677db55df76782dbd2930c5e1c1ea0 - flutter_local_notifications: 4cde75091f6327eb8517fa068a0a5950212d2086 flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12 GoogleAppMeasurement: f65fc137531af9ad647f1c0a42f3b6a4d3a98049 GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a GoogleUtilities: ea963c370a38a8069cc5f7ba4ca849a60b6d7d15 image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1 + IosAwnCore: b8601fbb37f7b3560f31b84ebf55a72f65812e05 local_auth_darwin: 66e40372f1c29f383a314c738c7446e2f7fdadc3 nanopb: 438bc412db1928dac798aa6fd75726007be04262 OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c @@ -363,6 +367,6 @@ SPEC CHECKSUMS: video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3 webview_flutter_wkwebview: 2a23822e9039b7b1bc52e5add778e5d89ad488d1 -PODFILE CHECKSUM: d7f4d1b71f8c708247c1078c4aec33a28c763405 +PODFILE CHECKSUM: 3bb356a4513d56583f2f2461d3d8eefb4cd4c3a4 COCOAPODS: 1.15.2 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 77985801..8e5d3b01 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -41,8 +41,8 @@ 4C588A6A63D12FBFE8C3D586 /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = ""; }; 4C7A2C30DCF835BA60FAD235 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 50BE974D08F66282C0031620 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - 6436409127A31CDB00820AF7 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; - 6436409227A31CD800820AF7 /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/InfoPlist.strings; sourceTree = ""; }; + 6436409227A31CDD00820AF7 /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/InfoPlist.strings; sourceTree = ""; }; + 6436409B27A31CD600820AF7 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; @@ -53,8 +53,6 @@ 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 6436409227A31CDD00820AF7 /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/InfoPlist.strings; sourceTree = ""; }; - 6436409B27A31CD600820AF7 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; C1B4A503715BC7B0F8826983 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -382,8 +380,10 @@ isa = XCBuildConfiguration; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { + APPLICATION_EXTENSION_API_ONLY = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; + BUILD_LIBRARY_FOR_DISTRIBUTION = NO; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; @@ -528,8 +528,10 @@ isa = XCBuildConfiguration; baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { + APPLICATION_EXTENSION_API_ONLY = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; + BUILD_LIBRARY_FOR_DISTRIBUTION = NO; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; @@ -568,8 +570,10 @@ isa = XCBuildConfiguration; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { + APPLICATION_EXTENSION_API_ONLY = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; + BUILD_LIBRARY_FOR_DISTRIBUTION = NO; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index d1887b8a..f52eb22e 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -1,7 +1,6 @@ import UIKit import Flutter -import flutter_local_notifications @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { @@ -9,15 +8,6 @@ import flutter_local_notifications _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { - - FlutterLocalNotificationsPlugin.setPluginRegistrantCallback { (registry) in - GeneratedPluginRegistrant.register(with: registry) - } - - if #available(iOS 10.0, *) { - UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate - } - GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } diff --git a/lib/backend/notifications/firebase_messaging_service.dart b/lib/backend/notifications/firebase_messaging_service.dart new file mode 100644 index 00000000..e6dfd349 --- /dev/null +++ b/lib/backend/notifications/firebase_messaging_service.dart @@ -0,0 +1,66 @@ +import 'dart:developer'; + +import 'package:firebase_messaging/firebase_messaging.dart'; +import 'package:hub/app_state.dart'; +import 'package:hub/backend/api_requests/api_calls.dart'; +import 'package:hub/shared/utils/log_util.dart'; + +import 'notification_service.dart'; + + +Future handleMessage(RemoteMessage message) async { + NotificationService.show(title: message.notification!.title!, body: message.notification!.body!, payload: Map.from(message.data)); +} + +class FirebaseMessagingService { + // Singleton instance + static final FirebaseMessagingService _instance = FirebaseMessagingService._internal(); + + // Factory constructor + factory FirebaseMessagingService() => _instance; + + // Private constructor + FirebaseMessagingService._internal(); + + final _firebaseMessaging = FirebaseMessaging.instance; + + Future initNotifications() async { + await _firebaseMessaging.requestPermission(); + + _refreshToken(); + + FirebaseMessaging.onBackgroundMessage(handleMessage); + + FirebaseMessaging.onMessage.listen((RemoteMessage message) { + handleMessage(message); + }); + } + + Future updateDeviceToken() async { + try { + final String? deviceToken = await _firebaseMessaging.getToken(); + + if (deviceToken != null) { + AppState().token = deviceToken; + + final ApiCallResponse? response = await PhpGroup.updToken.call(token: AppState().token, devid: AppState().devUUID, useruuid: AppState().userUUID); + + if (PhpGroup.updToken.error((response?.jsonBody ?? '')) == false) { + log('Token Atualizado com Sucesso!'); + } else { + log('Falha ao Atualizar Token: ${response?.jsonBody}'); + } + + } else { + log('Falha ao Pegar Token do Firebase'); + } + } catch (e, s) { + LogUtil.requestAPIFailed("updToken.php", "", "Atualizar Token", e, s); + } + } + + void _refreshToken() { + _firebaseMessaging.onTokenRefresh.listen((token) => updateDeviceToken); + } + +} \ No newline at end of file diff --git a/lib/backend/notifications/notification_service.dart b/lib/backend/notifications/notification_service.dart new file mode 100644 index 00000000..1aa9f370 --- /dev/null +++ b/lib/backend/notifications/notification_service.dart @@ -0,0 +1,105 @@ +import 'dart:developer'; + +import 'package:awesome_notifications/awesome_notifications.dart'; +import 'package:flutter/material.dart'; +import 'package:hub/flutter_flow/flutter_flow_util.dart'; + +class NotificationService { + static Future initialize() async { + await AwesomeNotifications().initialize( + null, + [ + NotificationChannel( + channelKey: 'basic_channel', + channelGroupKey: 'basic_channel', + channelName: 'Basic notifications', + channelDescription: 'Notification channel for tests', + importance: NotificationImportance.Max, + channelShowBadge: true, + playSound: true, + criticalAlerts: true, + onlyAlertOnce: true, + defaultColor: const Color(0xFF9D58D0), + ledColor: Colors.white) + ], + channelGroups: [ + NotificationChannelGroup( + channelGroupKey: 'basic_channel_group', + channelGroupName: 'group_1') + ], + debug: true); + await AwesomeNotifications() + .isNotificationAllowed() + .then((isAllowed) async { + if (!isAllowed) { + await AwesomeNotifications().requestPermissionToSendNotifications(); + } + }); + + await AwesomeNotifications().setListeners( + onActionReceivedMethod: onActionReceivedMethod, + onNotificationCreatedMethod: onNotificationCreatedMethod, + onNotificationDisplayedMethod: onNotificationDisplayedMethod, + onDismissActionReceivedMethod: onDismissActionReceivedMethod); + } + + static Future onActionReceivedMethod(ReceivedAction receivedAction) async { + // debugPrint('onActionReceivedMethod'); + // final payload = receivedAction.payload ?? {}; + // if (payload['navigate'] == 'true') { + // locator().navigateToWithParams(notificationRoute, {'title': payload['title']!, 'body': payload['body']!}); + // } + log("onActionReceivedMethod"); + showAlertDialog(AppState().context!, 'Test', 'Test', () async {}); + } + + static Future onNotificationCreatedMethod(ReceivedNotification receivedNotification) async { + log('onNotificationCreatedMethod'); + } + + static Future onNotificationDisplayedMethod(ReceivedNotification receivedNotification) async { + log('onNotificationDisplayedMethod'); + } + + static Future onDismissActionReceivedMethod(ReceivedAction receivedAction) async { + log('onDismissActionReceivedMethod'); + } + + static Future show({ + required final String title, + required final String body, + final String? summary, + final Map? payload, + final ActionType actionType = ActionType.Default, + final NotificationLayout notificationLayout = NotificationLayout.Default, + final NotificationCategory? category, + final String? bigPicture, + final List? actionButtons, + final bool scheduled = false, + final int? interval, + }) async { + assert(!scheduled || (scheduled && interval != null)); + await AwesomeNotifications().createNotification( + content: NotificationContent( + id: 0, + channelKey: 'basic_channel', + title: title, + body: body, + actionType: actionType, + notificationLayout: notificationLayout, + summary: summary, + category: category, + payload: payload, + bigPicture: bigPicture, + ), + actionButtons: actionButtons, + schedule: scheduled + ? NotificationInterval( + interval: interval, + timeZone: + await AwesomeNotifications().getLocalTimeZoneIdentifier(), + preciseAlarm: true) + : null + ); + } +} \ No newline at end of file diff --git a/lib/backend/push_notification/push_notification.dart b/lib/backend/push_notification/push_notification.dart deleted file mode 100644 index de4eefa7..00000000 --- a/lib/backend/push_notification/push_notification.dart +++ /dev/null @@ -1,181 +0,0 @@ -import 'dart:async'; -import 'dart:developer'; - -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:hub/firebase_options.dart'; - -class NotificationService { - // Singleton instance - static final NotificationService _instance = NotificationService._internal(); - - // Factory constructor - factory NotificationService() => _instance; - - // Private constructor - NotificationService._internal(); - - static final FirebaseMessaging _firebaseMessaging = - FirebaseMessaging.instance; - static final FlutterLocalNotificationsPlugin - _flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); - static bool _initialized = false; - - Future initialize() async { - if (_initialized) return; - _initialized = true; - - try { - await _requestPermissions(); - await _initializeLocalNotifications(); - - FirebaseMessaging.onBackgroundMessage( - _firebaseMessagingBackgroundHandler); - - FirebaseMessaging.onMessage.listen((RemoteMessage message) { - _printNotification(message, 'onMessage'); - }); - - FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) { - _printNotification(message, 'onMessageOpenedApp'); - }); - } catch (e) { - log('Error initializing notification manager: $e'); - } - } - - Future _printNotification(RemoteMessage message, String type) async { - log('Notification $type: ${message.messageId}'); - // Handle the notification display logic here - } - - Future _initializeLocalNotifications() async { - const AndroidInitializationSettings initializationSettingsAndroid = - AndroidInitializationSettings('@mipmap/ic_launcher'); - final DarwinInitializationSettings initializationSettingsIOS = - DarwinInitializationSettings( - onDidReceiveLocalNotification: - (int id, String? title, String? body, String? payload) async { - // Handle the notification received in foreground - }, - ); - final InitializationSettings initializationSettings = - InitializationSettings( - android: initializationSettingsAndroid, - iOS: initializationSettingsIOS, - ); - - await _flutterLocalNotificationsPlugin.initialize(initializationSettings, - onDidReceiveNotificationResponse: (payload) async => - log('Notification tapped: $payload'), - onDidReceiveBackgroundNotificationResponse: (payload) async => - log('Notification tapped in background: $payload')); - } - - Future _requestPermissions() async { - NotificationSettings settings = await _firebaseMessaging.requestPermission( - alert: true, - announcement: false, - badge: true, - carPlay: false, - criticalAlert: false, - provisional: false, - sound: true, - ); - - log('User granted permission: ${settings.authorizationStatus}'); - } - - Future subscribeToTopic(String topic) async { - try { - await _firebaseMessaging.subscribeToTopic(topic); - log('Subscribed to topic: $topic'); - } catch (e) { - log('Error subscribing to topic $topic: $e'); - } - } - - Future unsubscribeFromTopic(String topic) async { - try { - await _firebaseMessaging.unsubscribeFromTopic(topic); - log('Unsubscribed from topic: $topic'); - } catch (e) { - log('Error unsubscribing from topic $topic: $e'); - } - } -} - -@pragma('vm:entry-point') -Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async { - await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); - await setupFlutterNotifications(); - showFlutterNotification(message); - // If you're going to use other Firebase services in the background, such as Firestore, - // make sure you call `initializeApp` before using other Firebase services. - log('Handling a background message ${message.messageId}'); -} - -/// Create a [AndroidNotificationChannel] for heads up notifications -late AndroidNotificationChannel channel; - -bool isFlutterLocalNotificationsInitialized = false; - -Future setupFlutterNotifications() async { - if (isFlutterLocalNotificationsInitialized) { - return; - } - channel = const AndroidNotificationChannel( - 'high_importance_channel', // id - 'High Importance Notifications', // title - description: - 'This channel is used for important notifications.', // description - importance: Importance.high, - ); - - flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); - - /// Create an Android Notification Channel. - /// - /// We use this channel in the `AndroidManifest.xml` file to override the - /// default FCM channel to enable heads up notifications. - await flutterLocalNotificationsPlugin - .resolvePlatformSpecificImplementation< - AndroidFlutterLocalNotificationsPlugin>() - ?.createNotificationChannel(channel); - - /// Update the iOS foreground notification presentation options to allow - /// heads up notifications. - await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions( - alert: true, - badge: true, - sound: true, - ); - isFlutterLocalNotificationsInitialized = true; -} - -void showFlutterNotification(RemoteMessage message) { - RemoteNotification? notification = message.notification; - AndroidNotification? android = message.notification?.android; - if (notification != null && android != null && !kIsWeb) { - flutterLocalNotificationsPlugin.show( - notification.hashCode, - notification.title, - notification.body, - NotificationDetails( - android: AndroidNotificationDetails( - channel.id, - channel.name, - channelDescription: channel.description, - // TODO add a proper drawable resource to android, for now using - // one that already exists in example app. - icon: 'launch_background', - ), - ), - ); - } -} - -/// Initialize the [FlutterLocalNotificationsPlugin] package. -late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin; diff --git a/lib/backend/push_notification/push_notification_service.dart b/lib/backend/push_notification/push_notification_service.dart deleted file mode 100644 index a7ca841f..00000000 --- a/lib/backend/push_notification/push_notification_service.dart +++ /dev/null @@ -1,627 +0,0 @@ -import 'dart:async'; -import 'dart:developer'; -import 'dart:io'; -import 'dart:math' as math; - -import 'package:firebase_core/firebase_core.dart'; -import 'package:firebase_messaging/firebase_messaging.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_local_notifications/flutter_local_notifications.dart'; -import 'package:hub/actions/actions.dart'; -import 'package:hub/backend/api_requests/api_calls.dart'; -import 'package:hub/components/templates_components/access_notification_modal_template_component/access_notification_modal_template_component_widget.dart'; -import 'package:hub/components/templates_components/details_component/details_component_widget.dart'; -import 'package:hub/components/templates_components/message_notificaion_modal_template_component/message_notification_widget.dart'; -import 'package:hub/flutter_flow/flutter_flow_icon_button.dart'; -import 'package:hub/flutter_flow/flutter_flow_theme.dart'; -import 'package:hub/flutter_flow/flutter_flow_util.dart'; -import 'package:hub/flutter_flow/flutter_flow_widgets.dart'; -import 'package:rxdart/rxdart.dart'; - -class PushNotificationService { - final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance; - final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin = - FlutterLocalNotificationsPlugin(); - final BehaviorSubject _onMessage = - BehaviorSubject(); - final BehaviorSubject> _notificationDetails = - BehaviorSubject>(); - Subject getOnMessage() { - return _onMessage; - } - - PushNotificationService() { - log('PushNotificationService created'); - } - - Future initialize() async { - log('Initializing PushNotificationService'); - - FirebaseMessaging.onBackgroundMessage( - (RemoteMessage message) => _firebaseMessagingBackgroundHandler( - message, - _flutterLocalNotificationsPlugin, - ), - ); - _initializeLocalNotifications(); - _createNotificationChannels(); - await _requestPermissions(); - WidgetsBinding.instance.addPostFrameCallback((_) { - _listenToForegroundMessages(); - _listenToBackgroundMessages(); - _listenToNotificationClicks(); - }); - await updateDeviceToken(); - log('PushNotificationService initialized'); - } - - // OK - Future _requestPermissions() async { - NotificationSettings settings = await _firebaseMessaging.requestPermission( - alert: true, - badge: true, - sound: true, - ); - if (settings.authorizationStatus == AuthorizationStatus.authorized) { - log('Notification permissions granted'); - } else { - log('Notification permissions denied'); - } - } - - static Map validJsonFromString(String? jsonString) { - if (jsonString == null || jsonString.isEmpty) { - return {}; - } - - String correctedJson = jsonString.replaceAllMapped( - RegExp(r'([a-zA-Z0-9_]+)\s*:\s*([^",\}\]]+)'), (match) { - var key = '"${match[1]!}"'; - var value = match[2]!.trim(); - - bool isStringValue = !RegExp(r'^-?\d+(\.\d+)?$').hasMatch(value) && - value != 'true' && - value != 'false' && - value != 'null' && - !value.startsWith('{') && - !value.endsWith('}'); - - String quotedValue = isStringValue ? '"$value"' : value; - - return '$key: $quotedValue'; - }); - - correctedJson = - correctedJson.replaceAllMapped(RegExp(r'"{([^"]+)}"'), (match) { - return '{${match[1]!}}'; - }); - - try { - return jsonDecode(correctedJson); - } catch (e) { - return {}; - } - } - - void _initializeLocalNotifications() async { - try { - while (AppState().context == null) { - await Future.delayed(const Duration(milliseconds: 100)); - } - log("Context: ${AppState().context}"); - var initializationSettingsAndroid = - const AndroidInitializationSettings('mipmap/ic_fre_black'); - - var initializationSettingsIOS = const DarwinInitializationSettings( - requestAlertPermission: true, - requestBadgePermission: true, - requestSoundPermission: true, - ); - var initializationSettings = InitializationSettings( - android: initializationSettingsAndroid, - iOS: initializationSettingsIOS, - ); - _flutterLocalNotificationsPlugin.initialize( - initializationSettings, - onDidReceiveBackgroundNotificationResponse: (response) => - notificationTapBackground(response, _notificationDetails), - onDidReceiveNotificationResponse: (response) => - notificationTapBackground(response, _notificationDetails), - ); - } on Exception catch (e, s) { - log("Error initializing local notifications: $e"); - log(s.toString()); - } - } - - @pragma('vm:entry-point') - static void notificationTapBackground( - NotificationResponse response, _notificationDetails) async { - log("Notification: ${response.payload}"); - if (response.payload != null) { - try { - Map message = - validJsonFromString(response.payload ?? ''); - var data = _notificationDetails.value; - _handleNotificationClick(message, extra: data); - } catch (e) { - log('Error handling background notification: $e'); - } - } - } - - void _createNotificationChannels() { - List actions = [ - 'visit_request', - 'visit_response', - 'access', - 'mensagem', - 'enroll_cond', - 'miscellaneous' - ]; - for (String action in actions) { - _createNotificationChannel('channel_$action', "channel_$action"); - } - } - - void _createNotificationChannel(String channelId, String channelName) { - final androidNotificationChannel = AndroidNotificationChannel( - channelId, - channelName, - description: 'Channel for $channelName notifications', - importance: Importance.max, - ); - - AndroidFlutterLocalNotificationsPlugin() - .createNotificationChannel(androidNotificationChannel) - .catchError((error, stackTrace) { - log('Error creating notification channel: $error'); - log(stackTrace.toString()); - }); - } - - void _listenToForegroundMessages() { - FirebaseMessaging.onMessage.listen((RemoteMessage message) { - log("Message Foreground: ${message.data}"); - _onMessage.add(message); - _notificationDetails.add(message.toMap()['notification']); - _showNotification(message); - }).onError((error) { - log("Error listening to foreground messages: $error"); - }); - } - - void _listenToBackgroundMessages() { - FirebaseMessaging.onBackgroundMessage((RemoteMessage message) => - _firebaseMessagingBackgroundHandler( - message, _flutterLocalNotificationsPlugin)); - } - - void _listenToNotificationClicks() { - FirebaseMessaging.onMessageOpenedApp - .listen((RemoteMessage message) => _firebaseMessagingBackgroundHandler) - .onError((err) { - log("Error listening to notification clicks: $err"); - }); - } - - void configureTokenRefresh() { - _firebaseMessaging.onTokenRefresh - .listen(_handleTokenUpdate) - .onError((err) {}); - } - - Future _updateToken(String token) async { - AppState().token = token; - final ApiCallResponse? response = await _updateTokenOnServer(token); - if (_isTokenUpdateSuccessful(response)) { - log('Token update successful'); - } else { - log('Token update failed'); - } - } - - Future _handleTokenUpdate(String newToken) async { - await _updateToken(newToken); - } - - Future updateDeviceToken() async { - configureTokenRefresh(); - - final NotificationSettings settings = - await _requestNotificationPermission(); - if (Platform.isIOS) await _fetchAndLogApnsToken(settings); - - final String? deviceToken = await _firebaseMessaging.getToken(); - if (deviceToken != null) { - await _updateToken(deviceToken); - } else { - log('Failed to get device token'); - } - } - - Future _requestNotificationPermission() async { - final NotificationSettings settings = - await _firebaseMessaging.requestPermission(); - log(settings.authorizationStatus == AuthorizationStatus.authorized - ? 'User granted permission' - : 'User declined or has not accepted permission'); - return settings; - } - - Future _fetchAndLogApnsToken(NotificationSettings settings) async { - if (settings.authorizationStatus == AuthorizationStatus.authorized) { - final String? apnsToken = await _firebaseMessaging.getAPNSToken(); - log(apnsToken != null - ? 'APNS Token: $apnsToken' - : 'Failed to get APNS token'); - } - } - - Future _updateTokenOnServer(String deviceToken) async { - return await PhpGroup.updToken.call( - token: deviceToken, - devid: AppState().devUUID, - useruuid: AppState().userUUID, - ); - } - - bool _isTokenUpdateSuccessful(ApiCallResponse? response) { - return PhpGroup.updToken.error((response?.jsonBody ?? '')) == false; - } - - String _getChannelIdBasedOnClickAction(String clickAction) { - final baseId = clickAction.hashCode; - return 'channel_$baseId'; - } - - Future _showNotification(RemoteMessage message) async { - final String channelId = 'high_importance_channel'; - final AndroidNotificationDetails androidDetails = - AndroidNotificationDetails( - channelId, - 'High Importance Notifications', - channelDescription: 'This channel is used for important notifications.', - importance: Importance.high, - priority: Priority.high, - ); - final NotificationDetails generalNotificationDetails = - NotificationDetails(android: androidDetails); - - await _flutterLocalNotificationsPlugin.show( - math.Random().nextInt(1 << 30), - message.notification?.title, - message.notification?.body, - generalNotificationDetails, - payload: jsonEncode(message.data), - ); - } - - static _handleNotificationClick(Map payload, - {Map extra = const {}}) { - log("Payload _handleNotificationClick: $payload"); - switch (payload.isNotEmpty) { - case true: - NotificationHandler().handleMessage(payload, AppState().context, - extra: extra.isEmpty ? {} : extra); - break; - case false: - break; - } - } - - @pragma('vm:entry-point') - static Future _firebaseMessagingBackgroundHandler(RemoteMessage message, - FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin) async { - await Firebase.initializeApp(); - showFlutterNotification(message, _flutterLocalNotificationsPlugin); - log('Handling a background message ${message.messageId}'); - } - - static void showFlutterNotification(RemoteMessage message, - FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin) { - final RemoteNotification? notification = message.notification; - final AndroidNotification? android = message.notification?.android; - if (notification != null && android != null && !kIsWeb) { - _flutterLocalNotificationsPlugin.show( - notification.hashCode, - notification.title, - notification.body, - NotificationDetails( - android: AndroidNotificationDetails( - 'high_importance_channel', - 'High Importance Notifications', - channelDescription: - 'This channel is used for important notifications.', - icon: 'launch_background', - ), - ), - ); - } - } -} - -class NotificationHandler { - void handleMessage(Map message, BuildContext? context, - {Map extra = const {}}) { - message.forEach((key, value) {}); - - log("Message: $message"); - log("Extra: $extra"); - - if (context != null) { - switch (message['click_action']) { - case 'visit_request': - _showVisitRequestDialog(message, context); - break; - case '': - break; - case 'access': - _showAcessNotificationModal(message, context); - break; - case 'mensagem': - log("Extra Handle Message: $extra"); - _showMessageNotificationDialog(message, context, extra); - break; - case 'enroll_cond': - break; - default: - } - } - } - - String _getIdBasedOnUserType(Map message) { - if (message['USR_TIPO'].toString() == 'O') { - return message['USR_ID'].toString().isEmpty - ? '0' - : message['USR_ID'].toString(); - } else { - return message['USR_DOCUMENTO'].toString().isEmpty - ? '0' - : message['USR_DOCUMENTO'].toString(); - } - } - - void _showAcessNotificationModal( - Map message, BuildContext context) { - showDialog( - context: context, - builder: (BuildContext context) { - _getIdBasedOnUserType(message); - return Dialog( - backgroundColor: Colors.transparent, - child: AccessNotificationModalTemplateComponentWidget( - datetime: message['ACE_DATAHORA'].toString(), - drive: message['ACI_DESCRICAO'].toString(), - id: message['USR_TIPO'].toString() == 'O' - ? message['USR_ID'].toString() == '' - ? '0' - : message['USR_ID'].toString() - : message['USR_DOCUMENTO'].toString() == '' - ? '0' - : message['USR_DOCUMENTO'].toString(), - name: message['PES_NOME'].toString(), - type: message['USR_TIPO'], - ), - ); - }, - ); - } - - void _showMessageNotificationDialog(Map message, - BuildContext context, Map extra) { - showDialog( - useSafeArea: true, - barrierDismissible: true, - context: context, - builder: (BuildContext context) { - String localId = ''; - try { - localId = jsonDecode(message['local'])['CLI_ID']; - } catch (e) { - localId = message['local']['CLI_ID'].toString(); - } - - log("Mensagem: $message"); - log("Extra: $extra"); - - return GestureDetector( - onTap: () => Navigator.of(context).pop(), - child: SizedBox( - width: MediaQuery.of(context).size.width, - height: MediaQuery.of(context).size.height, - child: Dialog( - backgroundColor: Colors.transparent, - child: GestureDetector( - onTap: () => Navigator.of(context).pop(), - child: SizedBox( - width: MediaQuery.of(context).size.width, - height: MediaQuery.of(context).size.height, - child: MessageNotificationModalTemplateComponentWidget( - id: localId, - from: message['remetente'].toString(), - to: message['destinatario'].toString() == 'O' - ? 'Morador' - : 'Visitante', - message: extra['body'].toString().isEmpty - ? 'Unknown' - : extra['body'].toString(), - ), - ), - ), - ), - ), - ); - }, - ); - } - - void _showVisitRequestDialog( - Map message, BuildContext context) { - showDialog( - context: context, - barrierDismissible: true, - builder: (BuildContext context) { - _getIdBasedOnUserType(message); - return Dialog( - backgroundColor: Colors.transparent, - child: DetailsComponentWidget( - buttons: [ - FlutterFlowIconButton( - icon: const Icon(Icons.done), - onPressed: () async { - showDialog( - context: context, - builder: (context) { - return AlertDialog( - title: Text( - FFLocalizations.of(context).getVariableText( - ptText: 'Aprovar Visita', - enText: 'Approve Visit', - ), - ), - content: Text( - FFLocalizations.of(context).getVariableText( - ptText: - 'Você tem certeza que deseja aprovar essa visita?', - enText: - 'Are you sure you want to approve this visit?', - ), - ), - backgroundColor: - FlutterFlowTheme.of(context).primaryBackground, - actions: [ - FFButtonWidget( - text: FFLocalizations.of(context).getVariableText( - enText: 'No', - ptText: 'Não', - ), - onPressed: () { - Navigator.pop(context); - }, - options: FFButtonOptions( - width: 100, - height: 40, - color: FlutterFlowTheme.of(context) - .primaryBackground, - textStyle: TextStyle( - color: FlutterFlowTheme.of(context) - .primaryText, - ), - borderSide: BorderSide( - color: FlutterFlowTheme.of(context) - .primaryBackground, - width: 1, - ), - borderRadius: BorderRadius.circular(10)), - ), - FFButtonWidget( - text: FFLocalizations.of(context).getVariableText( - enText: 'Yes', - ptText: 'Sim', - ), - onPressed: () async { - await answersRequest.call( - context, - message['referencia'].toString(), - 'L', - 'Mensagem', - message['idVisitante'].toString(), - ); - }, - options: FFButtonOptions( - width: 100, - height: 40, - color: FlutterFlowTheme.of(context) - .primaryBackground, - textStyle: TextStyle( - color: - FlutterFlowTheme.of(context).primaryText, - ), - borderSide: BorderSide( - color: FlutterFlowTheme.of(context) - .primaryBackground, - width: 1, - ), - borderRadius: BorderRadius.circular(10), - ), - ), - ], - ); - }); - }, - ), - FlutterFlowIconButton( - icon: const Icon(Icons.close), - onPressed: () async { - showAlertDialog( - context, - FFLocalizations.of(context).getVariableText( - ptText: 'Bloquear Visita', - enText: 'Block Visit', - ), - FFLocalizations.of(context).getVariableText( - ptText: - 'Você tem certeza que deseja bloquear essa visita?', - enText: 'Are you sure you want to block this visit?', - ), () async { - await answersRequest.call( - context, - message['referencia'].toString(), - 'B', - 'Mensagem', - message['idVisitante'].toString(), - ); - }); - }, - ), - ], - labelsHashMap: Map.from({ - FFLocalizations.of(context).getVariableText( - enText: 'Visitor', - ptText: 'Visitante', - ): message['nomevisita'], - FFLocalizations.of(context).getVariableText( - enText: 'Reason', - ptText: 'Motivo', - ): message['motivo'], - FFLocalizations.of(context).getVariableText( - enText: 'Message', - ptText: 'Mensagem', - ): message['mensagem'], - }), - imagePath: - 'https://freaccess.com.br/freaccess/getImage.php?cliID=${AppState().cliUUID}&atividade=getFoto&Documento=${message['documento'] ?? ''}&tipo=E', - statusHashMap: [ - { - FFLocalizations.of(context).getVariableText( - enText: 'Active', - ptText: 'Ativo', - ): FlutterFlowTheme.of(context).warning, - }, - ], - ), - ); - }, - ); - } -} - -class PushNotificationManager { - final StreamController _onMessageReceivedController = - StreamController.broadcast(); - - Stream get onMessageReceived => - _onMessageReceivedController.stream; - - PushNotificationManager() { - FirebaseMessaging.onMessage.listen((RemoteMessage message) { - _onMessageReceivedController.add(message); - }); - } - - void dispose() { - _onMessageReceivedController.close(); - } -} diff --git a/lib/main.dart b/lib/main.dart index f8bcd7ba..33484406 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,85 +2,30 @@ import 'dart:developer'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_crashlytics/firebase_crashlytics.dart'; -import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_web_plugins/url_strategy.dart'; import 'package:hub/app_state.dart'; -import 'package:hub/firebase_options.dart'; +import 'package:hub/backend/notifications/firebase_messaging_service.dart'; +import 'package:hub/backend/notifications/notification_service.dart'; import 'package:hub/flutter_flow/flutter_flow_theme.dart'; +import 'package:hub/flutter_flow/flutter_flow_util.dart'; import 'package:hub/flutter_flow/internationalization.dart'; import 'package:hub/flutter_flow/nav/nav.dart'; -import 'package:hub/shared/utils/notification_util.dart'; import 'package:provider/provider.dart'; import 'package:responsive_framework/responsive_framework.dart'; final GlobalKey navigatorKey = GlobalKey(); -@pragma('vm:entry-point') -Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async { - if (!isFlutterLocalNotificationsInitialized) - await setupFlutterNotifications(); - if (!Firebase.apps.isNotEmpty) - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform); - if (message.data.isNotEmpty) { - log('Handling a background message ${message.messageId}'); - log('Message data: ${message.data}'); - showFlutterNotification(message); - } - log('Handling a background message ${message.messageId}'); -} - -late AndroidNotificationChannel channel; -bool isFlutterLocalNotificationsInitialized = false; -late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin; - -late final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance; - -Future setupFlutterNotifications() async { - if (isFlutterLocalNotificationsInitialized) return; - - channel = const AndroidNotificationChannel( - 'high_importance_channel', // id - 'High Importance Notifications', // title - description: - 'This channel is used for important notifications.', // description - importance: Importance.high, - ); - - flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); - - await flutterLocalNotificationsPlugin - .resolvePlatformSpecificImplementation< - AndroidFlutterLocalNotificationsPlugin>() - ?.createNotificationChannel(channel); - flutterLocalNotificationsPlugin.initialize( - InitializationSettings( - android: const AndroidInitializationSettings('ic_launcher'), - iOS: DarwinInitializationSettings(onDidReceiveLocalNotification: - (int id, String? title, String? body, String? payload) async { - log('Test'); - }), - ), - onDidReceiveBackgroundNotificationResponse: (details) => log('Test'), - onDidReceiveNotificationResponse: (details) => log('Test'), - ); - - isFlutterLocalNotificationsInitialized = true; -} - -Future initializeFirebase() async {} - Future initializeApp() async { WidgetsFlutterBinding.ensureInitialized(); - // await initializeFirebase(); - await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); - FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler); - await setupFlutterNotifications(); + + await Firebase.initializeApp(); + await FirebaseMessagingService().initNotifications(); + await NotificationService.initialize(); + setUrlStrategy(const PathUrlStrategy()); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); if (kDebugMode) { diff --git a/lib/pages/home_page/home_page_widget.dart b/lib/pages/home_page/home_page_widget.dart index d297bd63..9a78b86c 100644 --- a/lib/pages/home_page/home_page_widget.dart +++ b/lib/pages/home_page/home_page_widget.dart @@ -1,9 +1,9 @@ import 'dart:developer'; -import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:hub/actions/actions.dart'; +import 'package:hub/backend/notifications/firebase_messaging_service.dart'; import 'package:hub/backend/schema/enums/enums.dart'; import 'package:hub/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart'; import 'package:hub/components/organism_components/local_profile_component/local_profile_component_widget.dart'; @@ -15,7 +15,6 @@ import 'package:hub/flutter_flow/flutter_flow_util.dart'; import 'package:hub/flutter_flow/flutter_flow_widgets.dart'; import 'package:hub/flutter_flow/nav/nav.dart'; import 'package:hub/pages/home_page/home_page_model.dart'; -import 'package:hub/shared/utils/notification_util.dart'; import 'package:provider/provider.dart'; class HomePageWidget extends StatefulWidget { @@ -29,11 +28,7 @@ class _HomePageWidgetState extends State { late HomePageModel _model; bool localStatus = false; final scaffoldKey = GlobalKey(); - String? _token; - String? initialMessage; - bool _resolved = false; - static late final FirebaseMessaging _firebaseMessaging = - FirebaseMessaging.instance; + Future checkLocalStatus() async { localStatus = await checkLocals( @@ -50,35 +45,9 @@ class _HomePageWidgetState extends State { AppState().context = context; - () async => await _firebaseMessaging.requestPermission( - alert: true, - announcement: false, - badge: true, - carPlay: false, - criticalAlert: false, - provisional: false, - sound: true, - ); - - _firebaseMessaging.getInitialMessage().then( - (value) => setState( - () { - _resolved = true; - initialMessage = value?.data.toString(); - }, - ), - ); - - FirebaseMessaging.onMessage.listen((RemoteMessage message) { - log(message.data.toString()); - showFlutterNotification(message); - }); - - FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) { - log(message.data.toString()); - print('A new onMessageOpenedApp event was published!'); - showAlertDialog(context, 'Test', 'Test', () async {}); - }); + () async { + await FirebaseMessagingService().updateDeviceToken(); + }(); WidgetsBinding.instance.addPostFrameCallback((_) async { @override diff --git a/lib/pages/liberation_history/liberation_history_widget.dart b/lib/pages/liberation_history/liberation_history_widget.dart index 600978c7..3ab52e15 100644 --- a/lib/pages/liberation_history/liberation_history_widget.dart +++ b/lib/pages/liberation_history/liberation_history_widget.dart @@ -4,7 +4,6 @@ import 'dart:developer'; import 'package:hub/actions/actions.dart'; import 'package:hub/backend/api_requests/api_calls.dart'; -import 'package:hub/backend/push_notification/push_notification_service.dart'; import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart'; import 'package:hub/components/templates_components/details_component/details_component_widget.dart'; diff --git a/lib/shared/utils/notification_util.dart b/lib/shared/utils/notification_util.dart deleted file mode 100644 index 48e919e5..00000000 --- a/lib/shared/utils/notification_util.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:firebase_messaging/firebase_messaging.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter_local_notifications/flutter_local_notifications.dart'; -import 'package:hub/main.dart'; - -void showFlutterNotification(RemoteMessage message) { - RemoteNotification? notification = message.notification; - AndroidNotification? android = message.notification?.android; - if (notification != null && android != null && !kIsWeb) { - flutterLocalNotificationsPlugin.show( - notification.hashCode, - notification.title, - notification.body, - NotificationDetails( - android: AndroidNotificationDetails( - channel.id, - channel.name, - channelDescription: channel.description, - // one that already exists in example app. - icon: 'launch_background', - ), - ), - ); - } -} diff --git a/pubspec.lock b/pubspec.lock index 9f41d477..a0b48174 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -41,6 +41,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.0" + awesome_notifications: + dependency: "direct main" + description: + name: awesome_notifications + sha256: d9e46ce7f5171ee1e9b1c5bc6dc40bd77528561f592842ce97ce3a0a9ae155ef + url: "https://pub.dev" + source: hosted + version: "0.9.3+1" barcode: dependency: transitive description: @@ -173,10 +181,10 @@ packages: dependency: transitive description: name: crypto - sha256: "1dceb0cf05cb63a7852c11560060e53ec2f182079a16ced6f4395c5b0875baf8" + sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27 url: "https://pub.dev" source: hosted - version: "3.0.4" + version: "3.0.5" csslib: dependency: transitive description: @@ -518,30 +526,6 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.0" - flutter_local_notifications: - dependency: "direct main" - description: - name: flutter_local_notifications - sha256: c500d5d9e7e553f06b61877ca6b9c8b92c570a4c8db371038702e8ce57f8a50f - url: "https://pub.dev" - source: hosted - version: "17.2.2" - flutter_local_notifications_linux: - dependency: transitive - description: - name: flutter_local_notifications_linux - sha256: c49bd06165cad9beeb79090b18cd1eb0296f4bf4b23b84426e37dd7c027fc3af - url: "https://pub.dev" - source: hosted - version: "4.0.1" - flutter_local_notifications_platform_interface: - dependency: transitive - description: - name: flutter_local_notifications_platform_interface - sha256: "85f8d07fe708c1bdcf45037f2c0109753b26ae077e9d9e899d55971711a4ea66" - url: "https://pub.dev" - source: hosted - version: "7.2.0" flutter_localizations: dependency: "direct main" description: flutter @@ -1065,10 +1049,10 @@ packages: dependency: transitive description: name: permission_handler_android - sha256: eaf2a1ec4472775451e88ca6a7b86559ef2f1d1ed903942ed135e38ea0097dca + sha256: "76e4ab092c1b240d31177bb64d2b0bea43f43d0e23541ec866151b9f7b2490fa" url: "https://pub.dev" source: hosted - version: "12.0.8" + version: "12.0.12" permission_handler_apple: dependency: transitive description: @@ -1081,10 +1065,10 @@ packages: dependency: transitive description: name: permission_handler_html - sha256: "6cac773d389e045a8d4f85418d07ad58ef9e42a56e063629ce14c4c26344de24" + sha256: d220eb8476b466d58b161e10b3001d93999010a26228a3fb89c4280db1249546 url: "https://pub.dev" source: hosted - version: "0.1.2" + version: "0.1.3+1" permission_handler_platform_interface: dependency: transitive description: @@ -1362,14 +1346,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.6.1" - timezone: - dependency: transitive - description: - name: timezone - sha256: "2236ec079a174ce07434e89fcd3fcda430025eb7692244139a9cf54fdcf1fc7d" - url: "https://pub.dev" - source: hosted - version: "0.9.4" typed_data: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 3d3afb8a..d8c4a49a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -24,7 +24,6 @@ dependencies: crop_your_image: 1.1.0 csv: 6.0.0 device_info_plus: 10.1.0 - flutter_local_notifications: ^17.2.2 firebase_messaging: 15.0.1 dropdown_button2: 2.3.9 easy_debounce: 2.0.3 @@ -94,6 +93,7 @@ dependencies: qr_flutter: ^4.1.0 permission_handler: ^11.3.1 firebase_crashlytics: ^4.0.1 + awesome_notifications: ^0.9.3+1 dependency_overrides: http: 1.2.1