diff --git a/android/app/build.gradle b/android/app/build.gradle index 85f2127..fe59029 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -2,6 +2,7 @@ plugins { id "com.android.application" // START: FlutterFire Configuration id 'com.google.gms.google-services' + id 'com.google.firebase.crashlytics' // END: FlutterFire Configuration id "kotlin-android" // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. diff --git a/android/settings.gradle b/android/settings.gradle index f7d6575..9c623bb 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -21,6 +21,7 @@ plugins { id "com.android.application" version "7.3.0" apply false // START: FlutterFire Configuration id "com.google.gms.google-services" version "4.3.15" apply false + id "com.google.firebase.crashlytics" version "2.8.1" apply false // END: FlutterFire Configuration id "org.jetbrains.kotlin.android" version "1.9.10" apply false } diff --git a/lib/main.dart b/lib/main.dart index 5b6c353..1d07d16 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -4,6 +4,7 @@ import 'package:cheminova/provider/collect_kyc_provider.dart'; import 'package:cheminova/provider/user_provider.dart'; import 'package:cheminova/screens/splash_screen.dart'; 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'; @@ -28,6 +29,14 @@ Future main() async { await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); + FlutterError.onError = (errorDetails) { + FirebaseCrashlytics.instance.recordFlutterFatalError(errorDetails); + }; + PlatformDispatcher.instance.onError = (error, stack) { + FirebaseCrashlytics.instance.recordError(error, stack, fatal: true); + return true; + }; + if (!kIsWeb) { flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); @@ -40,13 +49,15 @@ Future main() async { 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())); + 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 = diff --git a/lib/models/notification_list_response.dart b/lib/models/notification_list_response.dart index 4db128d..90199a8 100644 --- a/lib/models/notification_list_response.dart +++ b/lib/models/notification_list_response.dart @@ -9,17 +9,17 @@ class NotificationListResponse { if (json['notifications'] != null) { notifications = []; json['notifications'].forEach((v) { - notifications!.add(new Notifications.fromJson(v)); + notifications!.add(Notifications.fromJson(v)); }); } } Map toJson() { - final Map data = new Map(); - data['return_message'] = this.returnMessage; - if (this.notifications != null) { + final Map data = {}; + data['return_message'] = returnMessage; + if (notifications != null) { data['notifications'] = - this.notifications!.map((v) => v.toJson()).toList(); + notifications!.map((v) => v.toJson()).toList(); } return data; } @@ -54,14 +54,14 @@ class Notifications { } Map toJson() { - final Map data = new Map(); - data['_id'] = this.sId; - data['title'] = this.title; - data['msg'] = this.msg; - data['added_for'] = this.addedFor; - data['createdAt'] = this.createdAt; - data['updatedAt'] = this.updatedAt; - data['__v'] = this.iV; + final Map data = {}; + data['_id'] = sId; + data['title'] = title; + data['msg'] = msg; + data['added_for'] = addedFor; + data['createdAt'] = createdAt; + data['updatedAt'] = updatedAt; + data['__v'] = iV; return data; } } diff --git a/lib/provider/collect_kyc_provider.dart b/lib/provider/collect_kyc_provider.dart index 4448adf..fd09b7c 100644 --- a/lib/provider/collect_kyc_provider.dart +++ b/lib/provider/collect_kyc_provider.dart @@ -3,7 +3,6 @@ import 'dart:io'; import 'package:cheminova/models/get_pd_response.dart'; import 'package:cheminova/screens/data_submit_successfull.dart'; import 'package:cheminova/services/api_client.dart'; -import 'package:cheminova/services/secure__storage_service.dart'; import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; @@ -217,10 +216,6 @@ class CollectKycProvider extends ChangeNotifier { } Future submitCollectKycForm(BuildContext context) async { - final dio = Dio(); - final token = await SecureStorageService().read(key: 'access_token'); - final headers = {'Authorization': 'Bearer $token'}; - // Construct the FormData final data = FormData.fromMap({ 'name': nameController.text.trim(), @@ -236,22 +231,28 @@ class CollectKycProvider extends ChangeNotifier { 'aadhar_number': aadharNumberController.text.trim(), 'gst_number': gstNumberController.text.trim(), if (panCard != null) - 'pan_img': await MultipartFile.fromFile(panCard!.path, filename: 'pan_card.jpg'), + 'pan_img': await MultipartFile.fromFile(panCard!.path, + filename: 'pan_card.jpg'), if (aadharCard != null) - 'aadhar_img': await MultipartFile.fromFile(aadharCard!.path, filename: 'aadhar_card.jpg'), + 'aadhar_img': await MultipartFile.fromFile(aadharCard!.path, + filename: 'aadhar_card.jpg'), if (gstRegistration != null) - 'gst_img': await MultipartFile.fromFile(gstRegistration!.path, filename: 'gst_registration.jpg'), + 'gst_img': await MultipartFile.fromFile(gstRegistration!.path, + filename: 'gst_registration.jpg'), if (pesticideLicense != null) - 'pesticide_license_img': await MultipartFile.fromFile(pesticideLicense!.path, filename: 'pesticide_license.jpg'), + 'pesticide_license_img': await MultipartFile.fromFile( + pesticideLicense!.path, + filename: 'pesticide_license.jpg'), if (selfieEntranceBoard != null) - 'selfie_entrance_img': await MultipartFile.fromFile(selfieEntranceBoard!.path, filename: 'selfie_entrance_board.jpg'), + 'selfie_entrance_img': await MultipartFile.fromFile( + selfieEntranceBoard!.path, + filename: 'selfie_entrance_board.jpg'), }); setLoading(true); try { - - Response response = await _apiClient.post(ApiUrls.createCollectKycUrl, - data: data); + Response response = + await _apiClient.post(ApiUrls.createCollectKycUrl, data: data); setLoading(false); @@ -278,4 +279,4 @@ class CollectKycProvider extends ChangeNotifier { } } } -} \ No newline at end of file +} diff --git a/lib/screens/home_screen.dart b/lib/screens/home_screen.dart index e37b3d4..2578470 100644 --- a/lib/screens/home_screen.dart +++ b/lib/screens/home_screen.dart @@ -12,7 +12,6 @@ import 'package:cheminova/screens/product_sales_data.dart'; import 'package:cheminova/screens/update_inventory_screen.dart'; import 'package:cheminova/screens/display_sales_screen.dart'; import 'package:cheminova/widgets/common_drawer.dart'; -import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:cheminova/widgets/common_background.dart'; import 'package:cheminova/screens/daily_tasks_screen.dart'; @@ -278,6 +277,11 @@ class _HomePageState extends State { ], ), ), + const SizedBox(height: 12), + TextButton( + onPressed: () => throw Exception(), + child: const Text("Throw Test Exception"), + ), ], ), ), diff --git a/lib/screens/products_manual_screen.dart b/lib/screens/products_manual_screen.dart index a54c389..84a7f63 100644 --- a/lib/screens/products_manual_screen.dart +++ b/lib/screens/products_manual_screen.dart @@ -5,7 +5,7 @@ import 'package:cheminova/widgets/common_app_bar.dart'; import 'package:cheminova/widgets/common_elevated_button.dart'; class ProductsManualScreen extends StatelessWidget { - const ProductsManualScreen({Key? key}) : super(key: key); + const ProductsManualScreen({super.key}); @override Widget build(BuildContext context) { diff --git a/lib/screens/update_inventory_screen.dart b/lib/screens/update_inventory_screen.dart index 4870b38..e26862a 100644 --- a/lib/screens/update_inventory_screen.dart +++ b/lib/screens/update_inventory_screen.dart @@ -178,8 +178,8 @@ class _ProductBlockState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text('Product: ${widget.product.name}',style: TextStyle(fontSize: 16),), - Text('SKU: ${widget.product.sku}',style: TextStyle(fontSize: 15),), + Text('Product: ${widget.product.name}',style: const TextStyle(fontSize: 16),), + Text('SKU: ${widget.product.sku}',style: const TextStyle(fontSize: 15),), const SizedBox(height: 8), TextField( controller: saleController, diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 8b519a4..9efb22b 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,7 +6,9 @@ import FlutterMacOS import Foundation import file_selector_macos +import firebase_analytics import firebase_core +import firebase_crashlytics import firebase_messaging import flutter_local_notifications import flutter_secure_storage_macos @@ -15,7 +17,9 @@ import path_provider_foundation func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) + FLTFirebaseAnalyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAnalyticsPlugin")) FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) + FLTFirebaseCrashlyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCrashlyticsPlugin")) FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin")) FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin")) FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin")) diff --git a/pubspec.lock b/pubspec.lock index 7b5b5bb..a6d5ad8 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -173,10 +173,10 @@ packages: dependency: transitive description: name: cross_file - sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32" + sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" url: "https://pub.dev" source: hosted - version: "0.3.4+1" + version: "0.3.4+2" crypto: dependency: transitive description: @@ -297,6 +297,30 @@ packages: url: "https://pub.dev" source: hosted version: "0.9.3+2" + firebase_analytics: + dependency: "direct main" + description: + name: firebase_analytics + sha256: "064e5b57b0693305946b7caa6a80ed80a918f46804c247b6cd7ed9cd327df48f" + url: "https://pub.dev" + source: hosted + version: "11.2.1" + firebase_analytics_platform_interface: + dependency: transitive + description: + name: firebase_analytics_platform_interface + sha256: d094547c9022c404b5ca39b7209607fc80e75e39d38875f050508fa4346b3e74 + url: "https://pub.dev" + source: hosted + version: "4.2.1" + firebase_analytics_web: + dependency: transitive + description: + name: firebase_analytics_web + sha256: "06dc023b0144c0df630a56b6262cc9e7d6069fe78148853d97614dbefb6ea923" + url: "https://pub.dev" + source: hosted + version: "0.5.9+1" firebase_core: dependency: "direct main" description: @@ -321,6 +345,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.17.4" + firebase_crashlytics: + dependency: "direct main" + description: + name: firebase_crashlytics + sha256: "30260e1b8ad1464b41ca4531b44ce63d752daaf2f12c92ca6cdcd82b270abecc" + url: "https://pub.dev" + source: hosted + version: "4.0.4" + firebase_crashlytics_platform_interface: + dependency: transitive + description: + name: firebase_crashlytics_platform_interface + sha256: a75e1826d92ea4e86e4a753c7b5d64b844a362676fa653185f1581c859186d18 + url: "https://pub.dev" + source: hosted + version: "3.6.40" firebase_messaging: dependency: "direct main" description: @@ -386,18 +426,18 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1" + sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "4.0.0" flutter_local_notifications: dependency: "direct main" description: name: flutter_local_notifications - sha256: dd6676d8c2926537eccdf9f72128bbb2a9d0814689527b17f92c248ff192eaf3 + sha256: c500d5d9e7e553f06b61877ca6b9c8b92c570a4c8db371038702e8ce57f8a50f url: "https://pub.dev" source: hosted - version: "17.2.1+2" + version: "17.2.2" flutter_local_notifications_linux: dependency: transitive description: @@ -540,10 +580,10 @@ packages: dependency: transitive description: name: geolocator_android - sha256: "00c7177a95823dd3ee35ef42fd8666cd27d219ae14cea472ac76a21dff43000b" + sha256: "7aefc530db47d90d0580b552df3242440a10fe60814496a979aa67aa98b1fd47" url: "https://pub.dev" source: hosted - version: "4.6.0" + version: "4.6.1" geolocator_apple: dependency: transitive description: @@ -628,26 +668,26 @@ packages: dependency: "direct main" description: name: image_picker - sha256: b6951e25b795d053a6ba03af5f710069c99349de9341af95155d52665cb4607c + sha256: "021834d9c0c3de46bf0fe40341fa07168407f694d9b2bb18d532dc1261867f7a" url: "https://pub.dev" source: hosted - version: "0.8.9" + version: "1.1.2" image_picker_android: dependency: transitive description: name: image_picker_android - sha256: "8c3168469b005a6dbf5ba01f795917ae4f4e71077d3d7f2049a0d25a4760393e" + sha256: c0e72ecd170b00a5590bb71238d57dc8ad22ee14c60c6b0d1a4e05cafbc5db4b url: "https://pub.dev" source: hosted - version: "0.8.12+8" + version: "0.8.12+11" image_picker_for_web: dependency: transitive description: name: image_picker_for_web - sha256: "869fe8a64771b7afbc99fc433a5f7be2fea4d1cb3d7c11a48b6b579eb9c797f0" + sha256: "65d94623e15372c5c51bebbcb820848d7bcb323836e12dfdba60b5d3a8b39e50" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "3.0.5" image_picker_ios: dependency: transitive description: @@ -700,10 +740,10 @@ packages: dependency: "direct main" description: name: intl - sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91" + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf url: "https://pub.dev" source: hosted - version: "0.17.0" + version: "0.19.0" io: dependency: transitive description: @@ -756,10 +796,10 @@ packages: dependency: transitive description: name: lints - sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290 + sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "4.0.0" logging: dependency: transitive description: @@ -836,18 +876,18 @@ packages: dependency: transitive description: name: path_provider - sha256: c9e7d3a4cd1410877472158bee69963a4579f78b68c65a2b7d40d1a7a88bb161 + sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378 url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.4" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: e84c8a53fe1510ef4582f118c7b4bdf15b03002b51d7c2b66983c65843d61193 + sha256: "490539678396d4c3c0b06efdaab75ae60675c3e0c66f72bc04c2e2c1e0e2abeb" url: "https://pub.dev" source: hosted - version: "2.2.8" + version: "2.2.9" path_provider_foundation: dependency: transitive description: @@ -892,10 +932,10 @@ packages: dependency: transitive description: name: permission_handler_android - sha256: b29a799ca03be9f999aa6c39f7de5209482d638e6f857f6b93b0875c618b7e54 + sha256: eaf2a1ec4472775451e88ca6a7b86559ef2f1d1ed903942ed135e38ea0097dca url: "https://pub.dev" source: hosted - version: "12.0.7" + version: "12.0.8" permission_handler_apple: dependency: transitive description: @@ -916,10 +956,10 @@ packages: dependency: transitive description: name: permission_handler_platform_interface - sha256: "48d4fcf201a1dad93ee869ab0d4101d084f49136ec82a8a06ed9cfeacab9fd20" + sha256: fe0ffe274d665be8e34f9c59705441a7d248edebbe5d9e3ec2665f88b79358ea url: "https://pub.dev" source: hosted - version: "4.2.1" + version: "4.2.2" permission_handler_windows: dependency: transitive description: @@ -1081,10 +1121,10 @@ packages: dependency: "direct main" description: name: table_calendar - sha256: "7f1270313c0cdb245b583ed8518982c01d4a7e95869b3c30abcbae3b642c45d0" + sha256: "4ca32b2fc919452c9974abd4c6ea611a63e33b9e4f0b8c38dba3ac1f4a6549d1" url: "https://pub.dev" source: hosted - version: "3.0.8" + version: "3.1.2" term_glyph: dependency: transitive description: @@ -1225,10 +1265,10 @@ packages: dependency: transitive description: name: win32 - sha256: a79dbe579cb51ecd6d30b17e0cae4e0ea15e2c0e66f69ad4198f22a6789e94f4 + sha256: "015002c060f1ae9f41a818f2d5640389cc05283e368be19dc8d77cecb43c40c9" url: "https://pub.dev" source: hosted - version: "5.5.1" + version: "5.5.3" xdg_directories: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 65f9faa..8a50ba8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -31,12 +31,12 @@ dependencies: flutter: sdk: flutter table_calendar: ^3.0.0 - image_picker: ^0.8.4+5 + image_picker: ^1.1.2 cupertino_icons: ^1.0.6 flutter_svg: ^2.0.10+1 flutter_gen: ^5.6.0 pinput: ^5.0.0 - intl: ^0.17.0 + intl: ^0.19.0 dio: ^5.5.0+1 flutter_secure_storage: ^9.2.2 provider: ^6.1.2 @@ -48,12 +48,14 @@ dependencies: firebase_core: ^3.3.0 firebase_messaging: ^15.0.4 flutter_local_notifications: ^17.2.1+2 + firebase_crashlytics: ^4.0.4 + firebase_analytics: ^11.2.1 dev_dependencies: flutter_test: sdk: flutter - flutter_lints: ^3.0.0 + flutter_lints: ^4.0.0 build_runner: flutter_gen_runner: