diff --git a/android/app/build.gradle b/android/app/build.gradle
index e2ee37a..85f2127 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -1,5 +1,8 @@
plugins {
id "com.android.application"
+ // START: FlutterFire Configuration
+ id 'com.google.gms.google-services'
+ // END: FlutterFire Configuration
id "kotlin-android"
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id "dev.flutter.flutter-gradle-plugin"
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index c29f86c..04c6c49 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -29,7 +29,17 @@
+
+
+
+
+
+
HomeProvider()),
- ],
- child: const MyApp()));
+@pragma('vm:entry-point')
+Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
+ await Firebase.initializeApp();
+ log("Handling a background message: ${message.data["data"]}");
}
-class MyApp extends StatelessWidget {
+AndroidNotificationChannel channel = const AndroidNotificationChannel(
+ 'High Importance Channel', 'High Importance Notifications',
+ importance: Importance.high);
+
+late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
+
+Future main() async {
+ WidgetsFlutterBinding.ensureInitialized();
+
+ await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
+
+ if (!kIsWeb) {
+ flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
+
+ FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
+
+ await FirebaseMessaging.instance.getInitialMessage().then((message) {});
+
+ FirebaseMessaging.onMessage.listen((RemoteMessage message) {
+ RemoteNotification? notification = message.notification;
+ AndroidNotification? android = message.notification?.android;
+ if (notification != null && android != null) {
+ flutterLocalNotificationsPlugin.show(
+ notification.hashCode,
+ notification.title,
+ notification.body,
+ NotificationDetails(
+ android: AndroidNotificationDetails(channel.id, channel.name,
+ icon: '@mipmap/ic_launcher', importance: Importance.max),
+ iOS: const DarwinNotificationDetails()));
+ const AndroidInitializationSettings initializationSettingsAndroid =
+ AndroidInitializationSettings('@mipmap/ic_launcher');
+ const DarwinInitializationSettings darwinInitializationSettings =
+ DarwinInitializationSettings();
+ var initSettings = const InitializationSettings(
+ android: initializationSettingsAndroid,
+ iOS: darwinInitializationSettings);
+ flutterLocalNotificationsPlugin.initialize(initSettings);
+ }
+ });
+
+ if (Platform.isAndroid) {
+ await flutterLocalNotificationsPlugin
+ .resolvePlatformSpecificImplementation<
+ AndroidFlutterLocalNotificationsPlugin>()
+ ?.requestNotificationsPermission();
+ await flutterLocalNotificationsPlugin
+ .resolvePlatformSpecificImplementation<
+ AndroidFlutterLocalNotificationsPlugin>()
+ ?.createNotificationChannel(channel);
+ }
+ if (Platform.isIOS) {
+ await flutterLocalNotificationsPlugin
+ .resolvePlatformSpecificImplementation<
+ IOSFlutterLocalNotificationsPlugin>()
+ ?.requestPermissions(alert: true, badge: true, sound: true);
+ }
+
+ await FirebaseMessaging.instance
+ .setForegroundNotificationPresentationOptions(
+ alert: true, badge: true, sound: true);
+ }
+
+ runApp(MultiProvider(providers: [
+ ChangeNotifierProvider(create: (context) => HomeProvider()),
+ ], child: const MyApp()));
+}
+
+class MyApp extends StatefulWidget {
const MyApp({super.key});
+ @override
+ State createState() => _MyAppState();
+}
+
+class _MyAppState extends State {
@override
Widget build(BuildContext context) {
return MaterialApp(
diff --git a/lib/notification_services.dart b/lib/notification_services.dart
new file mode 100644
index 0000000..6777ade
--- /dev/null
+++ b/lib/notification_services.dart
@@ -0,0 +1,165 @@
+import 'dart:io';
+
+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';
+
+class NotificationServices {
+ //initialising firebase message plugin
+ FirebaseMessaging messaging = FirebaseMessaging.instance;
+
+ //initialising firebase message plugin
+ final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
+ FlutterLocalNotificationsPlugin();
+
+ //function to initialise flutter local notification plugin to show notifications for android when app is active
+ void initLocalNotifications(
+ BuildContext context, RemoteMessage message) async {
+ var androidInitializationSettings =
+ const AndroidInitializationSettings('@mipmap/ic_launcher');
+ var iosInitializationSettings = const DarwinInitializationSettings();
+
+ var initializationSetting = InitializationSettings(
+ android: androidInitializationSettings, iOS: iosInitializationSettings);
+
+ await _flutterLocalNotificationsPlugin.initialize(initializationSetting,
+ onDidReceiveNotificationResponse: (payload) {
+ // handle interaction when app is active for android
+ handleMessage(context, message);
+ });
+ }
+
+ void firebaseInit(BuildContext context) {
+ FirebaseMessaging.onMessage.listen((message) {
+ RemoteNotification? notification = message.notification;
+ AndroidNotification? android = message.notification!.android;
+
+ if (kDebugMode) {
+ print("notifications title:${notification!.title}");
+ print("notifications body:${notification.body}");
+ print('count:${android!.count}');
+ print('data:${message.data.toString()}');
+ }
+
+ if (Platform.isIOS) {
+ forgroundMessage();
+ }
+
+ if (Platform.isAndroid) {
+ initLocalNotifications(context, message);
+ showNotification(message);
+ }
+ });
+ }
+
+ void requestNotificationPermission() async {
+ NotificationSettings settings = await messaging.requestPermission(
+ alert: true,
+ announcement: true,
+ badge: true,
+ carPlay: true,
+ criticalAlert: true,
+ provisional: true,
+ sound: true,
+ );
+
+ if (settings.authorizationStatus == AuthorizationStatus.authorized) {
+ if (kDebugMode) {
+ print('user granted permission');
+ }
+ } else if (settings.authorizationStatus ==
+ AuthorizationStatus.provisional) {
+ if (kDebugMode) {
+ print('user granted provisional permission');
+ }
+ } else {
+ //appsetting.AppSettings.openNotificationSettings();
+ if (kDebugMode) {
+ print('user denied permission');
+ }
+ }
+ }
+
+ // function to show visible notification when app is active
+ Future showNotification(RemoteMessage message) async {
+ AndroidNotificationChannel channel = AndroidNotificationChannel(
+ message.notification!.android!.channelId.toString(),
+ message.notification!.android!.channelId.toString(),
+ importance: Importance.max,
+ showBadge: true,
+ playSound: true,
+ sound: const RawResourceAndroidNotificationSound('jetsons_doorbell'));
+
+ AndroidNotificationDetails androidNotificationDetails =
+ AndroidNotificationDetails(
+ channel.id.toString(), channel.name.toString(),
+ channelDescription: 'your channel description',
+ importance: Importance.high,
+ priority: Priority.high,
+ playSound: true,
+ ticker: 'ticker',
+ sound: channel.sound
+ // sound: RawResourceAndroidNotificationSound('jetsons_doorbell')
+ // icon: largeIconPath
+ );
+
+ const DarwinNotificationDetails darwinNotificationDetails =
+ DarwinNotificationDetails(
+ presentAlert: true, presentBadge: true, presentSound: true);
+
+ NotificationDetails notificationDetails = NotificationDetails(
+ android: androidNotificationDetails, iOS: darwinNotificationDetails);
+
+ Future.delayed(Duration.zero, () {
+ _flutterLocalNotificationsPlugin.show(
+ 0,
+ message.notification!.title.toString(),
+ message.notification!.body.toString(),
+ notificationDetails,
+ );
+ });
+ }
+
+ //function to get device token on which we will send the notifications
+ Future getDeviceToken() async {
+ String? token = await messaging.getToken();
+ return token!;
+ }
+
+ void isTokenRefresh() async {
+ messaging.onTokenRefresh.listen((event) {
+ event.toString();
+ if (kDebugMode) {
+ print('refresh');
+ }
+ });
+ }
+
+ //handle tap on notification when app is in background or terminated
+ Future setupInteractMessage(BuildContext context) async {
+ // when app is terminated
+ RemoteMessage? initialMessage =
+ await FirebaseMessaging.instance.getInitialMessage();
+
+ if (initialMessage != null) {
+ handleMessage(context, initialMessage);
+ }
+
+ //when app ins background
+ FirebaseMessaging.onMessageOpenedApp.listen((event) {
+ handleMessage(context, event);
+ });
+ }
+
+ void handleMessage(BuildContext context, RemoteMessage message) {}
+
+ Future forgroundMessage() async {
+ await FirebaseMessaging.instance
+ .setForegroundNotificationPresentationOptions(
+ alert: true,
+ badge: true,
+ sound: true,
+ );
+ }
+}
diff --git a/lib/screens/home_screen.dart b/lib/screens/home_screen.dart
index a85e5c6..039a57a 100644
--- a/lib/screens/home_screen.dart
+++ b/lib/screens/home_screen.dart
@@ -1,3 +1,4 @@
+import 'package:cheminova/notification_services.dart';
import 'package:cheminova/provider/home_provider.dart';
import 'package:cheminova/screens/rejected_application_screen.dart';
import 'package:cheminova/screens/calendar_screen.dart';
@@ -13,6 +14,7 @@ import 'package:cheminova/screens/update_inventory_screen.dart';
import 'package:cheminova/widgets/common_app_bar.dart';
import 'package:cheminova/widgets/common_background.dart';
import 'package:cheminova/widgets/common_drawer.dart';
+import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
@@ -24,10 +26,19 @@ class HomePage extends StatefulWidget {
}
class _HomePageState extends State {
+ NotificationServices notificationServices = NotificationServices();
+
@override
void initState() {
Provider.of(context, listen: false).getProfile();
super.initState();
+ notificationServices.requestNotificationPermission();
+
+ notificationServices. getDeviceToken().then((value) {
+ if (kDebugMode) {
+ print('Device Token: $value');
+ }
+ });
}
@override
diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift
index 850b6d6..8b519a4 100644
--- a/macos/Flutter/GeneratedPluginRegistrant.swift
+++ b/macos/Flutter/GeneratedPluginRegistrant.swift
@@ -6,12 +6,18 @@ import FlutterMacOS
import Foundation
import file_selector_macos
+import firebase_core
+import firebase_messaging
+import flutter_local_notifications
import flutter_secure_storage_macos
import geolocator_apple
import path_provider_foundation
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
+ FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
+ FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin"))
+ FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin"))
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
diff --git a/pubspec.lock b/pubspec.lock
index 9e91a02..89c2ba1 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -9,6 +9,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "67.0.0"
+ _flutterfire_internals:
+ dependency: transitive
+ description:
+ name: _flutterfire_internals
+ sha256: b1595874fbc8f7a50da90f5d8f327bb0bfd6a95dc906c390efe991540c3b54aa
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.3.40"
analyzer:
dependency: transitive
description:
@@ -209,6 +217,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.2.0"
+ dbus:
+ dependency: transitive
+ description:
+ name: dbus
+ sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.7.10"
dio:
dependency: "direct main"
description:
@@ -281,6 +297,54 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.9.3+2"
+ firebase_core:
+ dependency: "direct main"
+ description:
+ name: firebase_core
+ sha256: "3187f4f8e49968573fd7403011dca67ba95aae419bc0d8131500fae160d94f92"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.3.0"
+ firebase_core_platform_interface:
+ dependency: transitive
+ description:
+ name: firebase_core_platform_interface
+ sha256: "3c3a1e92d6f4916c32deea79c4a7587aa0e9dbbe5889c7a16afcf005a485ee02"
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.2.0"
+ firebase_core_web:
+ dependency: transitive
+ description:
+ name: firebase_core_web
+ sha256: e8d1e22de72cb21cdcfc5eed7acddab3e99cd83f3b317f54f7a96c32f25fd11e
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.17.4"
+ firebase_messaging:
+ dependency: "direct main"
+ description:
+ name: firebase_messaging
+ sha256: "1b0a4f9ecbaf9007771bac152afad738ddfacc4b8431a7591c00829480d99553"
+ url: "https://pub.dev"
+ source: hosted
+ version: "15.0.4"
+ firebase_messaging_platform_interface:
+ dependency: transitive
+ description:
+ name: firebase_messaging_platform_interface
+ sha256: c5a6443e66ae064fe186901d740ee7ce648ca2a6fd0484b8c5e963849ac0fc28
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.5.42"
+ firebase_messaging_web:
+ dependency: transitive
+ description:
+ name: firebase_messaging_web
+ sha256: "232ef63b986467ae5b5577a09c2502b26e2e2aebab5b85e6c966a5ca9b038b89"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.8.12"
fixnum:
dependency: transitive
description:
@@ -326,6 +390,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.2"
+ flutter_local_notifications:
+ dependency: "direct main"
+ description:
+ name: flutter_local_notifications
+ sha256: dd6676d8c2926537eccdf9f72128bbb2a9d0814689527b17f92c248ff192eaf3
+ url: "https://pub.dev"
+ source: hosted
+ version: "17.2.1+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_plugin_android_lifecycle:
dependency: transitive
description:
@@ -1021,6 +1109,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
+ timezone:
+ dependency: transitive
+ description:
+ name: timezone
+ sha256: "2236ec079a174ce07434e89fcd3fcda430025eb7692244139a9cf54fdcf1fc7d"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.9.4"
timing:
dependency: transitive
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 9e24874..65f9faa 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -45,6 +45,9 @@ dependencies:
geocoding: ^3.0.0
pretty_dio_logger: ^1.3.1
csc_picker: ^0.2.7
+ firebase_core: ^3.3.0
+ firebase_messaging: ^15.0.4
+ flutter_local_notifications: ^17.2.1+2
dev_dependencies:
flutter_test:
diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc
index 6a1b9be..41dfcd2 100644
--- a/windows/flutter/generated_plugin_registrant.cc
+++ b/windows/flutter/generated_plugin_registrant.cc
@@ -7,6 +7,7 @@
#include "generated_plugin_registrant.h"
#include
+#include
#include
#include
#include
@@ -14,6 +15,8 @@
void RegisterPlugins(flutter::PluginRegistry* registry) {
FileSelectorWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FileSelectorWindows"));
+ FirebaseCorePluginCApiRegisterWithRegistrar(
+ registry->GetRegistrarForPlugin("FirebaseCorePluginCApi"));
FlutterSecureStorageWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin"));
GeolocatorWindowsRegisterWithRegistrar(
diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake
index e55e969..9c3f356 100644
--- a/windows/flutter/generated_plugins.cmake
+++ b/windows/flutter/generated_plugins.cmake
@@ -4,6 +4,7 @@
list(APPEND FLUTTER_PLUGIN_LIST
file_selector_windows
+ firebase_core
flutter_secure_storage_windows
geolocator_windows
permission_handler_windows