diff --git a/android/app/build.gradle b/android/app/build.gradle index 09cca07..a4a0a03 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -22,9 +22,24 @@ if (flutterVersionName == null) { } apply plugin: 'com.android.application' +apply plugin: 'com.google.gms.google-services' apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" +dependencies { + // Import the Firebase BoM + implementation platform('com.google.firebase:firebase-bom:31.5.0') + + + // TODO: Add the dependencies for Firebase products you want to use + // When using the BoM, don't specify versions in Firebase dependencies + implementation 'com.google.firebase:firebase-analytics' + + + // Add the dependencies for any other desired Firebase products + // https://firebase.google.com/docs/android/setup#available-libraries +} + android { compileSdkVersion 33 ndkVersion flutter.ndkVersion diff --git a/android/app/google-services.json b/android/app/google-services.json new file mode 100644 index 0000000..56d5f09 --- /dev/null +++ b/android/app/google-services.json @@ -0,0 +1,39 @@ +{ + "project_info": { + "project_number": "746262114789", + "project_id": "watermanagement-supplier", + "storage_bucket": "watermanagement-supplier.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:746262114789:android:05a70cd92e0cf15c90ff0c", + "android_client_info": { + "package_name": "com.arminta.supplier.watermanagement_supplier" + } + }, + "oauth_client": [ + { + "client_id": "746262114789-lpula7bqquhek2ml7din0hcl3rs033qe.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCEIPea7TLh2AmQyFtOLFuV5ioDyksqzec" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "746262114789-lpula7bqquhek2ml7din0hcl3rs033qe.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/android/build.gradle b/android/build.gradle index 83ae220..716cf6a 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -8,6 +8,7 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:7.1.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath 'com.google.gms:google-services:4.3.15' } } diff --git a/lib/dashboard.dart b/lib/dashboard.dart index dcd1e94..9ec836c 100644 --- a/lib/dashboard.dart +++ b/lib/dashboard.dart @@ -13,10 +13,9 @@ import 'package:watermanagement/settings.dart'; import 'package:image_picker/image_picker.dart'; import 'package:watermanagement/tankersview.dart'; import 'dart:io'; - import 'package:watermanagement/updateprofile.dart'; - import 'booking_requests.dart'; +import 'package:firebase_messaging/firebase_messaging.dart'; class Dashboard extends StatefulWidget { @@ -50,7 +49,48 @@ class _DashboardState extends State { print(response1); }*/ + @override + void initState() { + + super.initState(); + initialize(); + } + + initialize() async { + + + FirebaseMessaging messaging = FirebaseMessaging.instance; + + FirebaseMessaging.onMessage.listen((RemoteMessage event) { + print("message recieved"); + print(event.notification!.body); + }); + FirebaseMessaging.onMessageOpenedApp.listen((message) { + print('Message clicked!'); + }); + + FirebaseMessaging.onMessage.listen((RemoteMessage event) { + print("message recieved"); + print(event.notification!.body); + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text(event.notification!.body!), + content: Text(event.notification!.title!), + actions: [ + TextButton( + child: Text("Ok"), + onPressed: () { + Navigator.of(context).pop(); + }, + ) + ], + ); + }); + }); + } Future pickImageFromGallery() async { try { diff --git a/lib/fcm_notifications.dart b/lib/fcm_notifications.dart new file mode 100644 index 0000000..7802481 --- /dev/null +++ b/lib/fcm_notifications.dart @@ -0,0 +1,160 @@ +import 'package:firebase_messaging/firebase_messaging.dart'; +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'dart:io'; +import 'package:flutter/services.dart'; +import 'package:device_info_plus/device_info_plus.dart'; +import 'package:watermanagement/settings.dart'; + + +class FireBaseCore { + static String messageTokenEntity = "watermanagement_supplier"; + static final FirebaseMessaging firebaseMessaging = FirebaseMessaging.instance; + static FirebaseFirestore firestoredb = FirebaseFirestore.instance; + static CollectionReference messageTokenCollection = FirebaseFirestore.instance.collection(messageTokenEntity); + static final DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin(); + static Map deviceData={}; + static String fcmToken = ""; + static String deviceId = ""; + static String spKeyReference="FCM_TOKEN"; + static bool _initialized = false; + + static Future init() async { + if (!_initialized) { + // For iOS request permission first. + firebaseMessaging.requestPermission(); + + // For testing purposes print the Firebase Messaging token + String? token = await FirebaseMessaging.instance.getToken(); + print("FirebaseMessaging token: $token"); + + _initialized = true; + } + } + + static Future checkFcmTokenInFireStoreDbWithdeviceId() async { + await readDeviceInfo(); + await AppSettings.saveData("DEVICE_ID", deviceId, 'STRING'); + if(await AppSettings.getData(spKeyReference, 'STRING')==""){ + FirebaseFirestore.instance + .collection(messageTokenEntity) + .doc(deviceId) + .get() + .then((DocumentSnapshot documentSnapshot) async { + + if (documentSnapshot.exists) { + Map dbRow = documentSnapshot.data() as Map;; + // (snapshot.data as DocumentSnapshot)['username'] + await AppSettings.saveData(spKeyReference,dbRow['_fcmToken'], 'STRING'); + AppSettings.fcmId=await AppSettings.getData('FCM_TOKEN', 'STRING'); + print('Document exists on the database'); + } + else { + await addDeviceFcmTokenToFireStoreDb(); + } + }).catchError((error) { + print("checkFcmTokenInFireStoreDbWithdeviceId failed $error"); + }); + } + } + + static Future updateWithUserInfo(Map input) async { + await readDeviceInfo(); + try { + messageTokenCollection.doc(deviceId).update(input).catchError((error) { + print("Failed to add user: $error"); + }); + } catch (e) { + print(e); + } + } + + static Future createFcmToken() async { + //fcmToken = (await firebaseMessaging.getToken())!; + fcmToken = (await firebaseMessaging.getToken())!; + } + + static Future addDeviceFcmTokenToFireStoreDb() async { + await readDeviceInfo(); + await createFcmToken(); + + deviceData['_fcmToken'] = fcmToken; + await AppSettings.saveData(spKeyReference, fcmToken, 'STRING'); + await AppSettings.saveData("DEVICE_ID", deviceId, 'STRING'); + AppSettings.fcmId=await AppSettings.getData('FCM_TOKEN', 'STRING'); + // Call the users CollectionReference to add a new user + try { + return messageTokenCollection.doc(deviceId).set(deviceData).then((value) { + print("Device information store in fcm"); + }).catchError((error) { + print("Failed to add user: $error"); + }); + } catch (e) { + print(e); + } + } + + static Future readDeviceInfo() async { + try { + if (Platform.isAndroid) { + _readAndroidBuildData(await deviceInfoPlugin.androidInfo); + } else if (Platform.isIOS) { + _readIosDeviceInfo(await deviceInfoPlugin.iosInfo); + } + } on PlatformException { + deviceData = { + 'Error:': 'Failed to get platform version.' + }; + } + } + + static Map _readAndroidBuildData(AndroidDeviceInfo build) { + deviceId = build.androidId.toString(); + return deviceData = { + 'version.securityPatch': build.version.securityPatch, + 'version.sdkInt': build.version.sdkInt, + 'version.release': build.version.release, + 'version.previewSdkInt': build.version.previewSdkInt, + 'version.incremental': build.version.incremental, + 'version.codename': build.version.codename, + 'version.baseOS': build.version.baseOS, + 'board': build.board, + 'bootloader': build.bootloader, + 'brand': build.brand, + 'device': build.device, + 'display': build.display, + 'fingerprint': build.fingerprint, + 'hardware': build.hardware, + 'host': build.host, + 'id': build.id, + 'manufacturer': build.manufacturer, + 'model': build.model, + 'product': build.product, + 'supported32BitAbis': build.supported32BitAbis, + 'supported64BitAbis': build.supported64BitAbis, + 'supportedAbis': build.supportedAbis, + 'tags': build.tags, + 'type': build.type, + 'isPhysicalDevice': build.isPhysicalDevice, + 'deviceId': build.androidId, + 'systemFeatures': build.systemFeatures, + }; + } + + static Map _readIosDeviceInfo(IosDeviceInfo data) { + //deviceId = data.; + return deviceData = { + 'name': data.name, + 'systemName': data.systemName, + 'systemVersion': data.systemVersion, + 'model': data.model, + 'localizedModel': data.localizedModel, + 'deviceId': data.identifierForVendor, + 'isPhysicalDevice': data.isPhysicalDevice, + 'utsname.sysname:': data.utsname.sysname, + 'utsname.nodename:': data.utsname.nodename, + 'utsname.release:': data.utsname.release, + 'utsname.version:': data.utsname.version, + 'utsname.machine:': data.utsname.machine, + }; + } +} diff --git a/lib/main.dart b/lib/main.dart index f7acf80..e025211 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,12 +2,16 @@ import 'package:flutter/material.dart'; import 'package:sizer/sizer.dart'; import 'package:flutter/services.dart'; import 'package:watermanagement/splash_screen.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_messaging/firebase_messaging.dart'; void main () async { // Set default home. Widget _defaultHome = Splash(); WidgetsFlutterBinding.ensureInitialized(); + await Firebase.initializeApp(); + FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(alert: true,badge: true,sound: true); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]) .then((_) { runApp(Sizer( diff --git a/lib/settings.dart b/lib/settings.dart index 783dcdb..3e1ecf7 100644 --- a/lib/settings.dart +++ b/lib/settings.dart @@ -5,12 +5,12 @@ import 'package:flutter/services.dart'; import 'package:http/http.dart' as http; import 'package:fluttertoast/fluttertoast.dart'; import 'package:shared_preferences/shared_preferences.dart'; - import 'package:intl/intl.dart'; import 'package:flutter_styled_toast/flutter_styled_toast.dart'; import 'dart:async'; import 'package:geolocator/geolocator.dart'; import 'package:watermanagement/preloader.dart'; +import 'package:dio/dio.dart'; const Color primaryColor = Color(0XFF0D4E84); const Color greyColor = Color(0XFF8F8E8E); @@ -76,6 +76,8 @@ class AppSettings { static late Position position; static String long = "", lat = ""; late StreamSubscription positionStream; + static String fcmId=''; + static String serverToken='AAAArcCwMeU:APA91bEDVgDUWy7f7eIuTZDIkjNdzKHj2zA7pniMMjuCaXLRHry0aKEnMaGToxDtMKmEk4L3XWm9rwQ9MbbruUKAbzd_f1VZ72oe0u7Qqn5j1amXgxsvUkHNMUI1qXFGq6E1RbpkrG7a'; //api urls static String host = 'http://35.207.198.4:3000/api/'; @@ -759,7 +761,78 @@ class AppSettings { } + static Future sendNotification(var body,var titile)async{ + final postUrl = 'https://fcm.googleapis.com/fcm/send'; + var token = fcmId; + print('token : $token'); + + final data = { + "notification": {"body":body, "title": titile}, + "priority": "high", + "data": { + "click_action": "FLUTTER_NOTIFICATION_CLICK", + "id": "1", + "status": "done" + }, + "to": "$token" + }; + + final headers = { + 'content-type': 'application/json', + 'Authorization': 'key=$serverToken', + }; + + + BaseOptions options = BaseOptions( + headers: headers, + ); + + + try { + final response = await Dio(options).post(postUrl, + data: data); + if (response.statusCode == 200) { + longSuccessToast('Request notification sent to supplier'); + } else { + print('notification sending failed'); + // on failure do sth + } + } + catch(e){ + print('exception $e'); + } + + + + + } + + static Future sendNotificationFromApp(var body,var titile)async{ + http.post( + Uri.parse('https://fcm.googleapis.com/fcm/send' ), + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'key=$serverToken', + }, + body: jsonEncode( + { + 'notification': { + 'title': titile, + 'body': body, + + }, + 'priority': 'high', + 'data': { + 'click_action': 'FLUTTER_NOTIFICATION_CLICK', + 'id': '1', + 'status': 'done' + }, + 'to': fcmId, + }, + ), + ); + } diff --git a/lib/splash_screen.dart b/lib/splash_screen.dart index 5916aa7..cf7b392 100644 --- a/lib/splash_screen.dart +++ b/lib/splash_screen.dart @@ -1,12 +1,16 @@ +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:watermanagement/dashboard.dart'; import 'package:watermanagement/settings.dart'; import 'package:watermanagement/signup.dart'; - +import 'fcm_notifications.dart'; +import 'package:firebase_core/firebase_core.dart'; void main() async{ SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); + await Firebase.initializeApp(); runApp(new Splash()); } @@ -42,8 +46,22 @@ class _SplashScreenState extends State { bool _result = await AppSettings.isSigIn(); + /*store device information in firebase*/ + try{ + if(Platform.isIOS){ + await FireBaseCore.init(); + } + //await FireBaseCore.init(); + await FireBaseCore.checkFcmTokenInFireStoreDbWithdeviceId(); + // AppSettings.fcmId=await AppSettings.getData('FCM_TOKEN', 'STRING'); + } + catch(e){ + print(e); + } + if (_result) { await AppSettings.loadDataFromMemory(); + AppSettings.fcmId=await AppSettings.getData('FCM_TOKEN', 'STRING'); await AppSettings.getProfile(); _defaultHome = new Dashboard(); } diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index a1756cd..1952d66 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,13 +5,23 @@ import FlutterMacOS import Foundation +import cloud_firestore +import device_info_plus_macos +import firebase_core +import firebase_messaging +import flutter_local_notifications import geolocator_apple import location -import package_info_plus +import package_info_plus_macos import shared_preferences_foundation import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + FLTFirebaseFirestorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseFirestorePlugin")) + DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) + FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) + FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin")) + FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin")) GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin")) LocationPlugin.register(with: registry.registrar(forPlugin: "LocationPlugin")) FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin")) diff --git a/pubspec.lock b/pubspec.lock index 8373791..00aa85b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,13 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _flutterfire_internals: + dependency: transitive + description: + name: _flutterfire_internals + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" archive: dependency: transitive description: @@ -64,6 +71,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.1" + cloud_firestore: + dependency: "direct dev" + description: + name: cloud_firestore + url: "https://pub.dartlang.org" + source: hosted + version: "4.5.2" + cloud_firestore_platform_interface: + dependency: transitive + description: + name: cloud_firestore_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "5.12.1" + cloud_firestore_web: + dependency: transitive + description: + name: cloud_firestore_web + url: "https://pub.dartlang.org" + source: hosted + version: "3.4.2" collection: dependency: transitive description: @@ -106,6 +134,69 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + dbus: + dependency: transitive + description: + name: dbus + url: "https://pub.dartlang.org" + source: hosted + version: "0.7.4" + device_info_plus: + dependency: "direct dev" + description: + name: device_info_plus + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.4" + device_info_plus_linux: + dependency: transitive + description: + name: device_info_plus_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + device_info_plus_macos: + dependency: transitive + description: + name: device_info_plus_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.3" + device_info_plus_platform_interface: + dependency: transitive + description: + name: device_info_plus_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.6.1" + device_info_plus_web: + dependency: transitive + description: + name: device_info_plus_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + device_info_plus_windows: + dependency: transitive + description: + name: device_info_plus_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + device_information: + dependency: "direct dev" + description: + name: device_information + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.4" + dio: + dependency: "direct dev" + description: + name: dio + url: "https://pub.dartlang.org" + source: hosted + version: "5.1.1" fake_async: dependency: transitive description: @@ -119,7 +210,7 @@ packages: name: ffi url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "1.2.1" file: dependency: transitive description: @@ -127,6 +218,48 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "6.1.4" + firebase_core: + dependency: transitive + description: + name: firebase_core + url: "https://pub.dartlang.org" + source: hosted + version: "2.10.0" + firebase_core_platform_interface: + dependency: transitive + description: + name: firebase_core_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "4.6.0" + firebase_core_web: + dependency: transitive + description: + name: firebase_core_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.0" + firebase_messaging: + dependency: "direct dev" + description: + name: firebase_messaging + url: "https://pub.dartlang.org" + source: hosted + version: "14.4.1" + firebase_messaging_platform_interface: + dependency: transitive + description: + name: firebase_messaging_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "4.3.1" + firebase_messaging_web: + dependency: transitive + description: + name: firebase_messaging_web + url: "https://pub.dartlang.org" + source: hosted + version: "3.3.1" flutter: dependency: "direct main" description: flutter @@ -146,6 +279,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.5.1" + flutter_device_type: + dependency: "direct dev" + description: + name: flutter_device_type + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.0" flutter_launcher_icons: dependency: "direct dev" description: @@ -160,6 +300,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.1" + flutter_local_notifications: + dependency: "direct dev" + description: + name: flutter_local_notifications + url: "https://pub.dartlang.org" + source: hosted + version: "9.9.1" + flutter_local_notifications_linux: + dependency: transitive + description: + name: flutter_local_notifications_linux + url: "https://pub.dartlang.org" + source: hosted + version: "0.5.1" + flutter_local_notifications_platform_interface: + dependency: transitive + description: + name: flutter_local_notifications_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "5.0.0" flutter_localizations: dependency: transitive description: flutter @@ -286,7 +447,7 @@ packages: name: google_api_headers url: "https://pub.dartlang.org" source: hosted - version: "1.5.0+1" + version: "1.3.0" google_maps_flutter: dependency: "direct main" description: @@ -321,7 +482,7 @@ packages: name: google_maps_place_picker_mb url: "https://pub.dartlang.org" source: hosted - version: "3.0.1" + version: "2.0.0-mb.22" google_maps_webservice: dependency: "direct main" description: @@ -385,6 +546,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.6.3" + imei_plugin: + dependency: "direct dev" + description: + name: imei_plugin + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" intl: dependency: "direct dev" description: @@ -462,20 +630,55 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.0" + overlay_support: + dependency: "direct dev" + description: + name: overlay_support + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" package_info_plus: dependency: transitive description: name: package_info_plus url: "https://pub.dartlang.org" source: hosted - version: "3.0.3" + version: "1.4.2" + package_info_plus_linux: + dependency: transitive + description: + name: package_info_plus_linux + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.5" + package_info_plus_macos: + dependency: transitive + description: + name: package_info_plus_macos + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" package_info_plus_platform_interface: dependency: transitive description: name: package_info_plus_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "1.0.2" + package_info_plus_web: + dependency: transitive + description: + name: package_info_plus_web + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.6" + package_info_plus_windows: + dependency: transitive + description: + name: package_info_plus_windows + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.5" path: dependency: transitive description: @@ -517,7 +720,7 @@ packages: name: path_provider_windows url: "https://pub.dartlang.org" source: hosted - version: "2.1.5" + version: "2.0.7" petitparser: dependency: transitive description: @@ -670,6 +873,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.4.12" + timezone: + dependency: transitive + description: + name: timezone + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.0" tuple: dependency: "direct main" description: @@ -767,14 +977,14 @@ packages: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "3.1.3" + version: "2.6.1" xdg_directories: dependency: transitive description: name: xdg_directories url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "0.2.0+3" xml: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index d27e58f..e1ddba3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ dependencies: location: ^4.4.0 geolocator: ^9.0.2 - google_api_headers: ^1.5.0+1 + google_api_headers: ^1.2.0 google_maps_flutter: ^2.2.3 google_maps_webservice: ^0.0.20-nullsafety.5 http: ^0.13.5 @@ -42,11 +42,20 @@ dev_dependencies: intl: ^0.17.0 flutter_svg: ^1.0.1 flutter_styled_toast: ^2.1.3 - google_maps_place_picker_mb: ^3.0.1 + google_maps_place_picker_mb: ^2.0.0-mb.22 flutter_datetime_picker: ^1.5.1 date_time_picker: ^2.1.0 flutter_cupertino_datetime_picker: ^3.0.0 card_swiper: ^2.0.4 + firebase_messaging: ^14.4.1 + flutter_local_notifications: ^9.0.2 + cloud_firestore: ^4.5.2 + flutter_device_type: ^0.4.0 + imei_plugin: ^1.2.0 + device_information: ^0.0.4 + device_info_plus: ^3.2.4 + overlay_support: ^2.1.0 + dio: ^5.1.1