From 03fb8dade759a9b56fa1c7da4f1877c2357f198d Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Wed, 14 Apr 2021 07:15:23 +0545 Subject: [PATCH 1/4] upgrade and fix errors --- .../auth/data/model/user_repository.dart | 4 +- .../service/push_notification_service.dart | 56 ++--- lib/features/profile/data/model/device.dart | 7 +- lib/features/profile/data/model/user.dart | 7 +- .../presentation/pages/edit_profile.dart | 4 +- lib/main.dart | 7 +- lib/main_prod.dart | 7 +- pubspec.lock | 232 ++++++++++-------- pubspec.yaml | 50 ++-- 9 files changed, 202 insertions(+), 172 deletions(-) diff --git a/lib/features/auth/data/model/user_repository.dart b/lib/features/auth/data/model/user_repository.dart index 3988598..5b39a6b 100644 --- a/lib/features/auth/data/model/user_repository.dart +++ b/lib/features/auth/data/model/user_repository.dart @@ -139,7 +139,7 @@ class UserRepository with ChangeNotifier { ); UserModel existing = await userDBS.getSingle(_user.uid); if (existing == null) { - await userDBS.createItem(user, id: _user.uid); + await userDBS.create(user.toMap(), id: _user.uid); _fsUser = user; } else { await userDBS.updateData(_user.uid, { @@ -206,7 +206,7 @@ class UserRepository with ChangeNotifier { lastUpdatedAt: nowMS, uninstalled: false, ); - await userDeviceDBS.createItem(device, id: deviceId); + await userDeviceDBS.create(device.toMap(), id: deviceId); currentDevice = device; } notifyListeners(); diff --git a/lib/features/notification/data/service/push_notification_service.dart b/lib/features/notification/data/service/push_notification_service.dart index 4c4a38d..0e72963 100644 --- a/lib/features/notification/data/service/push_notification_service.dart +++ b/lib/features/notification/data/service/push_notification_service.dart @@ -4,7 +4,7 @@ import 'package:firebase_messaging/firebase_messaging.dart'; import 'dart:developer' as dev; class PushNotificationService { - final FirebaseMessaging _firebaseMessaging = FirebaseMessaging(); + final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance; bool initialized = false; String token; @@ -13,43 +13,41 @@ class PushNotificationService { FirebaseMessaging get firebaseMessaging => _firebaseMessaging; Future init() async { - if(!initialized) { - - if(Platform.isIOS) { + if (!initialized) { + if (Platform.isIOS) { _requestPermission(); } - _firebaseMessaging.configure( - onMessage: (Map message) { - dev.log("notification onMessage",error: message,time: DateTime.now()); - return; - }, - onResume: (Map message) { - dev.log("notification onMessage",error: message,time: DateTime.now()); - return; - }, - onLaunch: (Map message) { - dev.log("notification onMessage",error: message,time: DateTime.now()); - return; - }, - ); - token = await _firebaseMessaging.getToken(); - if(token != null) { + FirebaseMessaging.onMessage.listen((message) { + dev.log("notification onMessage", error: message, time: DateTime.now()); + return; + }); + + RemoteMessage message = await _firebaseMessaging.getInitialMessage(); + dev.log("notification onMessage", error: message, time: DateTime.now()); + + FirebaseMessaging.onMessageOpenedApp.listen((message) { + dev.log("notification onMessage", error: message, time: DateTime.now()); + }); + token = await _firebaseMessaging.getToken(); + if (token != null) { initialized = true; } - dev.log("token",error: token); + dev.log("token", error: token); return token; } return token; } - FutureOr _requestPermission() { - return _firebaseMessaging.requestNotificationPermissions( - const IosNotificationSettings( - sound: true, - badge: true, - alert: true, - provisional: false, - ) + FutureOr _requestPermission() async { + final settings = await _firebaseMessaging.requestPermission( + alert: true, + announcement: false, + badge: true, + carPlay: false, + criticalAlert: false, + provisional: false, + sound: true, ); + return settings.authorizationStatus == AuthorizationStatus.authorized; } } diff --git a/lib/features/profile/data/model/device.dart b/lib/features/profile/data/model/device.dart index 46b3cb4..144746b 100644 --- a/lib/features/profile/data/model/device.dart +++ b/lib/features/profile/data/model/device.dart @@ -1,7 +1,7 @@ import 'package:firebase_helpers/firebase_helpers.dart'; import 'package:firebasestarter/features/profile/data/model/device_field.dart'; -class Device extends DatabaseItem{ +class Device{ String id; DateTime createdAt; bool expired; @@ -10,7 +10,7 @@ class Device extends DatabaseItem{ DeviceDetails deviceInfo; String token; - Device({this.id, this.token,this.createdAt,this.expired,this.uninstalled,this.lastUpdatedAt,this.deviceInfo}):super(id); + Device({this.id, this.token,this.createdAt,this.expired,this.uninstalled,this.lastUpdatedAt,this.deviceInfo}); Device.fromDS(String id, Map data): id=id, @@ -19,8 +19,7 @@ class Device extends DatabaseItem{ uninstalled=data[DeviceFields.uninstalled] ?? false, lastUpdatedAt=data[DeviceFields.lastUpdatedAt], deviceInfo=DeviceDetails.fromJson(data[DeviceFields.deviceInfo]), - token=data[DeviceFields.token], - super(id); + token=data[DeviceFields.token]; Map toMap() { return { diff --git a/lib/features/profile/data/model/user.dart b/lib/features/profile/data/model/user.dart index dba33d8..66a9bfe 100644 --- a/lib/features/profile/data/model/user.dart +++ b/lib/features/profile/data/model/user.dart @@ -1,7 +1,7 @@ import 'package:firebase_helpers/firebase_helpers.dart'; import 'package:firebasestarter/features/profile/data/model/user_field.dart'; -class UserModel extends DatabaseItem { +class UserModel { String id; String name; String email; @@ -19,7 +19,7 @@ class UserModel extends DatabaseItem { this.registrationDate, this.photoUrl, this.introSeen, - this.buildNumber}):super(id); + this.buildNumber}); UserModel.fromDS(String id, Map data): id = id, @@ -29,8 +29,7 @@ class UserModel extends DatabaseItem { registrationDate = data[UserFields.registrationDate]?.toDate(), photoUrl = data[UserFields.photoUrl], buildNumber=data[UserFields.buildNumber], - introSeen=data[UserFields.introSeen], - super(id); + introSeen=data[UserFields.introSeen]; Map toMap() { final Map data = new Map(); diff --git a/lib/features/profile/presentation/pages/edit_profile.dart b/lib/features/profile/presentation/pages/edit_profile.dart index 8868952..e2c0004 100644 --- a/lib/features/profile/presentation/pages/edit_profile.dart +++ b/lib/features/profile/presentation/pages/edit_profile.dart @@ -155,11 +155,11 @@ class _EditProfileState extends State { } Future getImage(ImageSource source) async { - var image = await ImagePicker.pickImage( + var image = await ImagePicker().getImage( source: source); if(image == null) return; setState(() { - _image = image; + _image = File(image.path); _cropImage(); Navigator.pop(context); }); diff --git a/lib/main.dart b/lib/main.dart index 4292406..de32950 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -10,9 +10,8 @@ import 'package:firebasestarter/core/presentation/res/constants.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); - Crashlytics.instance.enableInDevMode = true; - FlutterError.onError = Crashlytics.instance.recordFlutterError; - runZoned(() { + FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError; + runZonedGuarded(() { runApp( Directionality( textDirection: TextDirection.ltr, @@ -30,5 +29,5 @@ void main() async { ), ), ); - }, onError: Crashlytics.instance.recordError); + }, FirebaseCrashlytics.instance.recordError); } diff --git a/lib/main_prod.dart b/lib/main_prod.dart index 1114b4d..2c232c7 100644 --- a/lib/main_prod.dart +++ b/lib/main_prod.dart @@ -10,9 +10,8 @@ import 'package:firebasestarter/core/presentation/res/constants.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); - // Crashlytics.instance.enableInDevMode = true; - FlutterError.onError = Crashlytics.instance.recordFlutterError; - runZoned(() { + FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError; + runZonedGuarded(() { runApp( Provider( child: App(), @@ -22,5 +21,5 @@ void main() async { ), ), ); - }, onError: Crashlytics.instance.recordError); + }, FirebaseCrashlytics.instance.recordError); } diff --git a/pubspec.lock b/pubspec.lock index 05255ad..8c0050c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -35,35 +35,35 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.5.0-nullsafety.1" + version: "2.5.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.1" + version: "2.1.0" change_app_package_name: dependency: "direct dev" description: name: change_app_package_name url: "https://pub.dartlang.org" source: hosted - version: "0.1.2" + version: "1.0.0" characters: dependency: transitive description: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.3" + version: "1.1.0" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.1" + version: "1.2.0" cli_util: dependency: transitive description: @@ -77,35 +77,35 @@ packages: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.1" + version: "1.1.0" cloud_firestore: dependency: "direct main" description: name: cloud_firestore url: "https://pub.dartlang.org" source: hosted - version: "0.14.3+1" + version: "1.0.4" cloud_firestore_platform_interface: dependency: transitive description: name: cloud_firestore_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.2.0" + version: "4.0.1" cloud_firestore_web: dependency: transitive description: name: cloud_firestore_web url: "https://pub.dartlang.org" source: hosted - version: "0.2.1+1" + version: "1.0.4" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.15.0-nullsafety.3" + version: "1.15.0" convert: dependency: transitive description: @@ -114,12 +114,12 @@ packages: source: hosted version: "2.1.1" crypto: - dependency: transitive + dependency: "direct overridden" description: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "2.1.5" + version: "3.0.1" csslib: dependency: transitive description: @@ -140,154 +140,182 @@ packages: name: device_info url: "https://pub.dartlang.org" source: hosted - version: "0.4.2+7" + version: "2.0.0" device_info_platform_interface: dependency: transitive description: name: device_info_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "2.0.1" fake_async: dependency: transitive description: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.1" + version: "1.2.0" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" file: dependency: transitive description: name: file url: "https://pub.dartlang.org" source: hosted - version: "6.0.0-nullsafety.2" + version: "6.0.0" firebase: dependency: transitive description: name: firebase url: "https://pub.dartlang.org" source: hosted - version: "7.3.0" + version: "9.0.1" firebase_analytics: dependency: "direct main" description: name: firebase_analytics url: "https://pub.dartlang.org" source: hosted - version: "6.2.0" + version: "7.1.1" firebase_analytics_platform_interface: dependency: transitive description: name: firebase_analytics_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "1.1.0" firebase_analytics_web: dependency: transitive description: name: firebase_analytics_web url: "https://pub.dartlang.org" source: hosted - version: "0.1.1" + version: "0.2.0+1" firebase_auth: dependency: "direct main" description: name: firebase_auth url: "https://pub.dartlang.org" source: hosted - version: "0.18.3+1" + version: "1.1.0" firebase_auth_platform_interface: dependency: transitive description: name: firebase_auth_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.1.3" + version: "4.1.0" firebase_auth_web: dependency: transitive description: name: firebase_auth_web url: "https://pub.dartlang.org" source: hosted - version: "0.3.2+1" + version: "1.0.6" firebase_core: dependency: "direct main" description: name: firebase_core url: "https://pub.dartlang.org" source: hosted - version: "0.5.2+1" + version: "1.0.3" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "4.0.0" firebase_core_web: dependency: transitive description: name: firebase_core_web url: "https://pub.dartlang.org" source: hosted - version: "0.2.1+1" + version: "1.0.2" firebase_crashlytics: dependency: "direct main" description: name: firebase_crashlytics url: "https://pub.dartlang.org" source: hosted - version: "0.2.3+1" + version: "2.0.0" firebase_crashlytics_platform_interface: dependency: transitive description: name: firebase_crashlytics_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" + version: "3.0.0" firebase_helpers: dependency: "direct main" description: name: firebase_helpers url: "https://pub.dartlang.org" source: hosted - version: "0.2.2" + version: "0.3.1" firebase_messaging: dependency: "direct main" description: name: firebase_messaging url: "https://pub.dartlang.org" source: hosted - version: "7.0.3" + version: "9.1.1" + firebase_messaging_platform_interface: + dependency: transitive + description: + name: firebase_messaging_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + firebase_messaging_web: + dependency: transitive + description: + name: firebase_messaging_web + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" firebase_remote_config: dependency: "direct main" description: name: firebase_remote_config url: "https://pub.dartlang.org" source: hosted - version: "0.4.2" + version: "0.9.0-dev.2" + firebase_remote_config_platform_interface: + dependency: transitive + description: + name: firebase_remote_config_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0-dev.1" firebase_storage: dependency: "direct main" description: name: firebase_storage url: "https://pub.dartlang.org" source: hosted - version: "5.1.0" + version: "8.0.3" firebase_storage_platform_interface: dependency: transitive description: name: firebase_storage_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "2.0.1" firebase_storage_web: dependency: transitive description: name: firebase_storage_web url: "https://pub.dartlang.org" source: hosted - version: "0.1.1" + version: "1.0.3" flutter: dependency: "direct main" description: flutter @@ -306,7 +334,7 @@ packages: name: flutter_automation url: "https://pub.dartlang.org" source: hosted - version: "1.3.3" + version: "1.4.0" flutter_driver: dependency: transitive description: flutter @@ -330,14 +358,14 @@ packages: name: flutter_plugin_android_lifecycle url: "https://pub.dartlang.org" source: hosted - version: "1.0.8" + version: "2.0.1" flutter_svg: dependency: "direct main" description: name: flutter_svg url: "https://pub.dartlang.org" source: hosted - version: "0.18.1" + version: "0.21.0+1" flutter_swiper: dependency: "direct main" description: @@ -373,28 +401,28 @@ packages: name: google_fonts url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "2.0.0" google_sign_in: dependency: "direct main" description: name: google_sign_in url: "https://pub.dartlang.org" source: hosted - version: "4.5.3" + version: "5.0.1" google_sign_in_platform_interface: dependency: transitive description: name: google_sign_in_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.1.2" + version: "2.0.1" google_sign_in_web: dependency: transitive description: name: google_sign_in_web url: "https://pub.dartlang.org" source: hosted - version: "0.9.1+1" + version: "0.10.0" html: dependency: transitive description: @@ -403,54 +431,61 @@ packages: source: hosted version: "0.14.0+3" http: - dependency: transitive + dependency: "direct overridden" description: name: http url: "https://pub.dartlang.org" source: hosted - version: "0.12.2" + version: "0.13.1" http_parser: dependency: transitive description: name: http_parser url: "https://pub.dartlang.org" source: hosted - version: "3.1.4" + version: "4.0.0" image_cropper: dependency: "direct main" description: name: image_cropper url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.4.0" image_picker: dependency: "direct main" description: name: image_picker url: "https://pub.dartlang.org" source: hosted - version: "0.6.7+6" + version: "0.7.4" + image_picker_for_web: + dependency: transitive + description: + name: image_picker_for_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" image_picker_platform_interface: dependency: transitive description: name: image_picker_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "2.1.0" integration_test: dependency: "direct dev" description: name: integration_test url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "1.0.2+2" intl: - dependency: transitive + dependency: "direct overridden" description: name: intl url: "https://pub.dartlang.org" source: hosted - version: "0.16.1" + version: "0.17.0" intl_translation: dependency: "direct dev" description: @@ -464,35 +499,28 @@ packages: name: js url: "https://pub.dartlang.org" source: hosted - version: "0.6.2" - json_rpc_2: - dependency: transitive - description: - name: json_rpc_2 - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.2" + version: "0.6.3" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.10-nullsafety.1" + version: "0.12.10" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.3" + version: "1.3.0" nested: dependency: transitive description: name: nested url: "https://pub.dartlang.org" source: hosted - version: "0.0.4" + version: "1.0.0" node_interop: dependency: transitive description: @@ -520,98 +548,105 @@ packages: name: package_info url: "https://pub.dartlang.org" source: hosted - version: "0.4.3" + version: "2.0.0" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.1" + version: "1.8.0" path_drawing: dependency: transitive description: name: path_drawing url: "https://pub.dartlang.org" source: hosted - version: "0.4.1+1" + version: "0.5.0" path_parsing: dependency: transitive description: name: path_parsing url: "https://pub.dartlang.org" source: hosted - version: "0.1.4" + version: "0.2.0" path_provider: dependency: transitive description: name: path_provider url: "https://pub.dartlang.org" source: hosted - version: "1.6.14" + version: "2.0.1" path_provider_linux: dependency: transitive description: name: path_provider_linux url: "https://pub.dartlang.org" source: hosted - version: "0.0.1+2" + version: "2.0.0" path_provider_macos: dependency: transitive description: name: path_provider_macos url: "https://pub.dartlang.org" source: hosted - version: "0.0.4+3" + version: "2.0.0" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "2.0.1" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" pedantic: dependency: transitive description: name: pedantic url: "https://pub.dartlang.org" source: hosted - version: "1.9.0" + version: "1.11.0" petitparser: - dependency: transitive + dependency: "direct overridden" description: name: petitparser url: "https://pub.dartlang.org" source: hosted - version: "3.0.4" + version: "4.1.0" platform: dependency: transitive description: name: platform url: "https://pub.dartlang.org" source: hosted - version: "3.0.0-nullsafety.2" + version: "3.0.0" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.2" + version: "2.0.0" process: dependency: transitive description: name: process url: "https://pub.dartlang.org" source: hosted - version: "4.0.0-nullsafety.2" + version: "4.0.0" provider: dependency: "direct main" description: name: provider url: "https://pub.dartlang.org" source: hosted - version: "4.3.2+1" + version: "5.0.0" pub_semver: dependency: transitive description: @@ -625,7 +660,7 @@ packages: name: quiver url: "https://pub.dartlang.org" source: hosted - version: "2.1.3" + version: "3.0.1" sky_engine: dependency: transitive description: flutter @@ -637,28 +672,28 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.2" + version: "1.8.0" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.1" + version: "1.10.0" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.1" + version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.1" + version: "1.1.0" sync_http: dependency: transitive description: @@ -672,14 +707,14 @@ packages: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.1" + version: "1.2.0" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.19-nullsafety.2" + version: "0.2.19" transformer_page_view: dependency: transitive description: @@ -693,14 +728,14 @@ packages: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.3" + version: "1.3.0" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.3" + version: "2.1.0" vm_service: dependency: transitive description: @@ -708,13 +743,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "5.5.0" - vm_service_client: - dependency: transitive - description: - name: vm_service_client - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.6+2" watcher: dependency: transitive description: @@ -722,34 +750,34 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.9.7+15" - web_socket_channel: + webdriver: dependency: transitive description: - name: web_socket_channel + name: webdriver url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" - webdriver: + version: "2.1.2" + win32: dependency: transitive description: - name: webdriver + name: win32 url: "https://pub.dartlang.org" source: hosted - version: "2.1.2" + version: "2.0.5" xdg_directories: dependency: transitive description: name: xdg_directories url: "https://pub.dartlang.org" source: hosted - version: "0.1.2" + version: "0.2.0" xml: dependency: transitive description: name: xml url: "https://pub.dartlang.org" source: hosted - version: "4.2.0" + version: "5.1.0" yaml: dependency: transitive description: @@ -758,5 +786,5 @@ packages: source: hosted version: "2.2.1" sdks: - dart: ">=2.10.0-110 <2.11.0" - flutter: ">=1.20.0 <2.0.0" + dart: ">=2.12.0 <3.0.0" + flutter: ">=1.24.0-7.0" diff --git a/pubspec.yaml b/pubspec.yaml index 9aa033e..aa85940 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -10,32 +10,40 @@ dependencies: sdk: flutter flutter_localizations: sdk: flutter - cloud_firestore: ^0.14.3+1 - device_info: ^0.4.2+6 - firebase_analytics: ^6.2.0 - firebase_auth: ^0.18.3+1 - firebase_core: ^0.5.2+1 - firebase_crashlytics: ^0.2.3+1 - firebase_helpers: ^0.2.2 - firebase_messaging: ^7.0.3 - firebase_remote_config: ^0.4.2 - firebase_storage: ^5.1.0 + cloud_firestore: ^1.0.4 + device_info: ^2.0.0 + firebase_analytics: ^7.1.1 + firebase_auth: ^1.1.0 + firebase_core: ^1.0.3 + firebase_crashlytics: ^2.0.0 + firebase_helpers: ^0.3.1 + firebase_messaging: ^9.1.1 + firebase_remote_config: ^0.9.0-dev.2 + firebase_storage: ^8.0.3 flutter_auth_buttons: ^0.9.0 - flutter_svg: ^0.18.0 + flutter_svg: ^0.21.0+1 flutter_swiper: ^1.1.6 - google_fonts: ^1.1.0 - google_sign_in: ^4.5.3 - image_cropper: ^1.3.0 - image_picker: ^0.6.7+4 - package_info: ^0.4.3 - provider: ^4.3.2 + google_fonts: ^2.0.0 + google_sign_in: ^5.0.1 + image_cropper: ^1.4.0 + image_picker: ^0.7.4 + package_info: ^2.0.0 + provider: ^5.0.0 + +dependency_overrides: + crypto: ^3.0.0 + http: ^0.13.0 + intl: 0.17.0 + petitparser: ^4.1.0 + dev_dependencies: flutter_test: sdk: flutter - change_app_package_name: ^0.1.2 - integration_test: ^1.0.0 - flutter_automation: ^1.3.2 - intl_translation: ^0.17.0 + change_app_package_name: ^1.0.0 + flutter_automation: ^1.4.0 + integration_test: ^1.0.2+2 + intl_translation: ^0.17.10+1 + flutter: uses-material-design: true flutter_intl: From 7077b45c07d22d4e0005efdf8688fe6f19e3034a Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Wed, 11 Aug 2021 19:22:21 +0545 Subject: [PATCH 2/4] upgrade to null safety and fix errors --- integration_test/app_test.dart | 4 +- lib/core/presentation/res/analytics.dart | 4 +- lib/core/presentation/res/app_config.dart | 2 +- lib/core/presentation/res/routes.dart | 3 +- lib/core/presentation/res/themes.dart | 2 +- .../auth/data/model/user_repository.dart | 56 ++-- .../auth/presentation/pages/home.dart | 2 +- .../auth/presentation/pages/login.dart | 22 +- .../auth/presentation/pages/user_info.dart | 10 +- .../presentation/widgets/auth_dialog.dart | 12 +- .../auth/presentation/widgets/login.dart | 28 +- .../auth/presentation/widgets/signup.dart | 42 +-- .../service/push_notification_service.dart | 6 +- .../onboarding/presentation/pages/intro.dart | 6 +- lib/features/profile/data/model/device.dart | 24 +- lib/features/profile/data/model/user.dart | 16 +- .../profile/data/service/user_db_service.dart | 4 +- .../presentation/pages/edit_profile.dart | 59 ++-- .../profile/presentation/pages/profile.dart | 14 +- .../profile/presentation/widgets/avatar.dart | 14 +- lib/generated/intl/messages_all.dart | 4 +- lib/generated/intl/messages_en.dart | 2 +- lib/generated/l10n.dart | 4 +- pubspec.lock | 267 ++++++------------ pubspec.yaml | 52 ++-- test/widget_test.dart | 4 +- 26 files changed, 275 insertions(+), 388 deletions(-) diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index 3a2571e..d0e4962 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -13,12 +13,12 @@ void main() { await tester.pumpAndSettle(); expect( find.byWidgetPredicate((Widget widget) => - widget is Text && widget.data.startsWith('Login')), + widget is Text && widget.data!.startsWith('Login')), findsOneWidget); final loginFinder = find.byWidgetPredicate((widget) => widget is RaisedButton && widget.child is Text && - (widget.child as Text).data.startsWith('Login')); + (widget.child as Text).data!.startsWith('Login')); expect(loginFinder, findsOneWidget); await tester.tap(loginFinder); await tester.pumpAndSettle(); diff --git a/lib/core/presentation/res/analytics.dart b/lib/core/presentation/res/analytics.dart index 910bbca..2f5e32a 100644 --- a/lib/core/presentation/res/analytics.dart +++ b/lib/core/presentation/res/analytics.dart @@ -19,7 +19,7 @@ class AnalyticsScreenNames { FirebaseAnalytics _getAnalytics(BuildContext context) => Provider.of(context, listen: false); -Future logEvent(BuildContext context, String name, {Map params}) { +Future logEvent(BuildContext context, String name, {Map? params}) { return _getAnalytics(context).logEvent(name: name, parameters: params); } @@ -27,7 +27,7 @@ Future setCurrentScreen(BuildContext context, String name) { return _getAnalytics(context).setCurrentScreen(screenName: name); } -Future setUserProperties(BuildContext context, {String id, String name, String email}) async { +Future setUserProperties(BuildContext context, {String? id, String? name, String? email}) async { await _getAnalytics(context).setUserId(id); await _getAnalytics(context).setUserProperty(name: "email", value: email); await _getAnalytics(context).setUserProperty(name: "name", value: name); diff --git a/lib/core/presentation/res/app_config.dart b/lib/core/presentation/res/app_config.dart index 1d5e89d..19f858c 100644 --- a/lib/core/presentation/res/app_config.dart +++ b/lib/core/presentation/res/app_config.dart @@ -9,5 +9,5 @@ class AppConfig { final String appTitle; final AppFlavor buildFlavor; - AppConfig({@required this.appTitle, @required this.buildFlavor}); + AppConfig({required this.appTitle, required this.buildFlavor}); } \ No newline at end of file diff --git a/lib/core/presentation/res/routes.dart b/lib/core/presentation/res/routes.dart index 9cb7949..410612a 100644 --- a/lib/core/presentation/res/routes.dart +++ b/lib/core/presentation/res/routes.dart @@ -1,3 +1,4 @@ +import 'package:firebasestarter/features/profile/data/model/user.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:firebasestarter/features/auth/presentation/pages/home.dart'; @@ -25,7 +26,7 @@ class AppRoutes { case userInfo: return UserInfoPage(); case editProfile: - return EditProfile(user: settings.arguments,); + return EditProfile(user: settings.arguments as UserModel?,); case profile: return UserProfile(); case splash: diff --git a/lib/core/presentation/res/themes.dart b/lib/core/presentation/res/themes.dart index 6637984..01d4f8d 100644 --- a/lib/core/presentation/res/themes.dart +++ b/lib/core/presentation/res/themes.dart @@ -4,7 +4,7 @@ import 'package:firebasestarter/core/presentation/res/colors.dart'; import 'package:firebasestarter/core/presentation/res/sizes.dart'; class AppThemes { - static BuildContext context; + static late BuildContext context; static final ThemeData defaultTheme = ThemeData( primaryColor: AppColors.primaryColor, accentColor: AppColors.accentColor, diff --git a/lib/features/auth/data/model/user_repository.dart b/lib/features/auth/data/model/user_repository.dart index 5b39a6b..1931d78 100644 --- a/lib/features/auth/data/model/user_repository.dart +++ b/lib/features/auth/data/model/user_repository.dart @@ -18,15 +18,15 @@ enum Status { Uninitialized, Authenticated, Authenticating, Unauthenticated } class UserRepository with ChangeNotifier { FirebaseAuth _auth; - User _user; + User? _user; GoogleSignIn _googleSignIn; Status _status = Status.Uninitialized; - String _error; - StreamSubscription _userListener; - UserModel _fsUser; - Device currentDevice; + String? _error; + late StreamSubscription _userListener; + UserModel? _fsUser; + Device? currentDevice; final PushNotificationService pnService; - bool _loading; + bool? _loading; UserRepository.instance(this.pnService) : _auth = FirebaseAuth.instance, @@ -36,11 +36,11 @@ class UserRepository with ChangeNotifier { _auth.authStateChanges().listen(_onAuthStateChanged); } - String get error => _error; + String? get error => _error; Status get status => _status; - User get fbUser => _user; - UserModel get user => _fsUser; - bool get isLoading => _loading; + User? get fbUser => _user; + UserModel? get user => _fsUser; + bool? get isLoading => _loading; Future signIn(String email, String password) async { try { @@ -50,7 +50,7 @@ class UserRepository with ChangeNotifier { _error = ''; return true; } catch (e) { - _error = e.message; + _error = e.toString(); _status = Status.Unauthenticated; notifyListeners(); return false; @@ -66,7 +66,7 @@ class UserRepository with ChangeNotifier { _error = ''; return true; } catch (e) { - _error = e.message; + _error = e.toString(); _status = Status.Unauthenticated; notifyListeners(); return false; @@ -77,18 +77,18 @@ class UserRepository with ChangeNotifier { try { _status = Status.Authenticating; notifyListeners(); - final GoogleSignInAccount googleUser = await _googleSignIn.signIn(); + final GoogleSignInAccount googleUser = await (_googleSignIn.signIn() as FutureOr); final GoogleSignInAuthentication googleAuth = await googleUser.authentication; final GoogleAuthCredential credential = GoogleAuthProvider.credential( accessToken: googleAuth.accessToken, idToken: googleAuth.idToken, - ); + ) as GoogleAuthCredential; await _auth.signInWithCredential(credential); _error = ''; return true; } catch (e) { - _error = e.message; + _error = e.toString(); _status = Status.Unauthenticated; notifyListeners(); return false; @@ -105,7 +105,7 @@ class UserRepository with ChangeNotifier { return Future.delayed(Duration.zero); } - Future _onAuthStateChanged(User firebaseUser) async { + Future _onAuthStateChanged(User? firebaseUser) async { if (firebaseUser == null) { _status = Status.Unauthenticated; _fsUser = null; @@ -113,7 +113,7 @@ class UserRepository with ChangeNotifier { } else { _user = firebaseUser; _saveUserRecord(); - _userListener = userDBS.streamSingle(_user.uid).listen((user) { + _userListener = userDBS.streamSingle(_user!.uid).listen((user) { _fsUser = user; _loading = false; notifyListeners(); @@ -128,21 +128,21 @@ class UserRepository with ChangeNotifier { PackageInfo packageInfo = await PackageInfo.fromPlatform(); int buildNumber = int.parse(packageInfo.buildNumber); UserModel user = UserModel( - email: _user.email, - name: _user.displayName, - photoUrl: _user.photoURL, - id: _user.uid, + email: _user!.email, + name: _user!.displayName, + photoUrl: _user!.photoURL, + id: _user!.uid, registrationDate: DateTime.now().toUtc(), lastLoggedIn: DateTime.now().toUtc(), buildNumber: buildNumber, introSeen: false, ); - UserModel existing = await userDBS.getSingle(_user.uid); + UserModel? existing = await userDBS.getSingle(_user!.uid); if (existing == null) { - await userDBS.create(user.toMap(), id: _user.uid); + await userDBS.create(user.toMap(), id: _user!.uid); _fsUser = user; } else { - await userDBS.updateData(_user.uid, { + await userDBS.updateData(_user!.uid, { UserFields.lastLoggedIn: FieldValue.serverTimestamp(), UserFields.buildNumber: buildNumber, }); @@ -152,8 +152,8 @@ class UserRepository with ChangeNotifier { Future _saveDevice(UserModel user) async { DeviceInfoPlugin devicePlugin = DeviceInfoPlugin(); - String deviceId; - DeviceDetails deviceDescription; + String? deviceId; + DeviceDetails? deviceDescription; if (Platform.isAndroid) { AndroidDeviceInfo deviceInfo = await devicePlugin.androidInfo; deviceId = deviceInfo.androidId; @@ -178,14 +178,14 @@ class UserRepository with ChangeNotifier { int buildNumber = int.parse(packageInfo.buildNumber); final nowMS = DateTime.now().toUtc().millisecondsSinceEpoch; if (user.buildNumber != buildNumber) { - userDBS.updateData(user.id, { + userDBS.updateData(user.id!, { UserFields.buildNumber: buildNumber, UserFields.lastUpdated: nowMS, }); } userDeviceDBS.collection = "${AppDBConstants.usersCollection}/${user.id}/devices"; - Device exsiting = await userDeviceDBS.getSingle(deviceId); + Device? exsiting = await userDeviceDBS.getSingle(deviceId!); if (exsiting != null) { var token = exsiting.token ?? await pnService.init(); await userDeviceDBS.updateData(deviceId, { diff --git a/lib/features/auth/presentation/pages/home.dart b/lib/features/auth/presentation/pages/home.dart index 7e18733..f0888b4 100644 --- a/lib/features/auth/presentation/pages/home.dart +++ b/lib/features/auth/presentation/pages/home.dart @@ -20,7 +20,7 @@ class AuthHomePage extends StatelessWidget { case Status.Authenticated: setUserProperties(context,id: user.fbUser?.uid, name: user.fbUser?.displayName, email: user.fbUser?.email); setCurrentScreen(context, AnalyticsScreenNames.userInfo); - if(user.isLoading) return Splash(); + if(user.isLoading!) return Splash(); return user.user?.introSeen ?? false ? HomePage() : IntroPage(); case Status.Uninitialized: default: diff --git a/lib/features/auth/presentation/pages/login.dart b/lib/features/auth/presentation/pages/login.dart index 0f52a8b..cb4530f 100644 --- a/lib/features/auth/presentation/pages/login.dart +++ b/lib/features/auth/presentation/pages/login.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:flutter_auth_buttons/flutter_auth_buttons.dart'; +import 'package:auth_buttons/auth_buttons.dart'; import 'package:firebasestarter/generated/l10n.dart'; import '../../data/model/user_repository.dart'; import '../widgets/auth_dialog.dart'; @@ -12,8 +12,8 @@ class WelcomePage extends StatefulWidget { class _WelcomePageState extends State { final GlobalKey _key = GlobalKey(); - bool _authVisible; - int _selectedTab; + late bool _authVisible; + int? _selectedTab; @override void initState() { @@ -40,14 +40,14 @@ class _WelcomePageState extends State { children: [ const SizedBox(height: kToolbarHeight), Text( - S.of(context).loginPageTitleText, - style: Theme.of(context).textTheme.display2.copyWith( + S.of(context)!.loginPageTitleText, + style: Theme.of(context).textTheme.display2!.copyWith( color: Colors.white, fontWeight: FontWeight.w900, fontFamily: "Frank"), ), Text( - S.of(context).loginPageSubtitleText, + S.of(context)!.loginPageSubtitleText, style: TextStyle(color: Colors.white, fontSize: 20.0), ), const SizedBox(height: 40.0), @@ -59,7 +59,7 @@ class _WelcomePageState extends State { child: RaisedButton( elevation: 0, highlightElevation: 0, - child: Text(S.of(context).loginButtonText), + child: Text(S.of(context)!.loginButtonText), onPressed: () => setState(() { _authVisible = true; _selectedTab = 0; @@ -70,7 +70,7 @@ class _WelcomePageState extends State { Expanded( child: OutlineButton( textColor: Colors.white, - child: Text(S.of(context).signupButtonText), + child: Text(S.of(context)!.signupButtonText), onPressed: () => setState(() { _authVisible = true; _selectedTab = 1; @@ -82,11 +82,11 @@ class _WelcomePageState extends State { ), ), const SizedBox(height: 50.0), - GoogleSignInButton( - text: S.of(context).googleButtonText, + GoogleAuthButton( + text: S.of(context)!.googleButtonText, onPressed: () async { if (!await user.signInWithGoogle()) - _key.currentState.showSnackBar(SnackBar( + _key.currentState!.showSnackBar(SnackBar( content: Text("Something is wrong"), )); }, diff --git a/lib/features/auth/presentation/pages/user_info.dart b/lib/features/auth/presentation/pages/user_info.dart index 1a24c36..210e47e 100644 --- a/lib/features/auth/presentation/pages/user_info.dart +++ b/lib/features/auth/presentation/pages/user_info.dart @@ -6,22 +6,22 @@ import 'package:firebasestarter/generated/l10n.dart'; import '../../data/model/user_repository.dart'; class UserInfoPage extends StatelessWidget { - final User user; + final User? user; - const UserInfoPage({Key key, this.user}) : super(key: key); + const UserInfoPage({Key? key, this.user}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text(S.of(context).profilePageTitle), + title: Text(S.of(context)!.profilePageTitle), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Text(user.email), + Text(user!.email!), RaisedButton( - child: Text(S.of(context).logoutButtonText), + child: Text(S.of(context)!.logoutButtonText), onPressed: () { logEvent(context, AppAnalyticsEvents.logOut); Provider.of(context, listen: false).signOut(); diff --git a/lib/features/auth/presentation/widgets/auth_dialog.dart b/lib/features/auth/presentation/widgets/auth_dialog.dart index effc24f..94d1e05 100644 --- a/lib/features/auth/presentation/widgets/auth_dialog.dart +++ b/lib/features/auth/presentation/widgets/auth_dialog.dart @@ -3,15 +3,15 @@ import './login.dart'; import './signup.dart'; class AuthDialog extends StatefulWidget { - final int selectedTab; - final Function onClose; - const AuthDialog({Key key, this.selectedTab, this.onClose}) : super(key: key); + final int? selectedTab; + final Function? onClose; + const AuthDialog({Key? key, this.selectedTab, this.onClose}) : super(key: key); @override _AuthDialogState createState() => _AuthDialogState(); } class _AuthDialogState extends State { - int _selectedTab; + int? _selectedTab; @override void initState() { super.initState(); @@ -22,7 +22,7 @@ class _AuthDialogState extends State { Widget build(BuildContext context) { return Center( child: DefaultTabController( - initialIndex: _selectedTab, + initialIndex: _selectedTab!, length: 2, child: Column( mainAxisSize: MainAxisSize.min, @@ -54,7 +54,7 @@ class _AuthDialogState extends State { color: Colors.white, icon: Icon(Icons.clear), onPressed: () => widget.onClose != null - ? widget.onClose() + ? widget.onClose!() : Navigator.pop(context), ), ], diff --git a/lib/features/auth/presentation/widgets/login.dart b/lib/features/auth/presentation/widgets/login.dart index a717d42..3a65908 100644 --- a/lib/features/auth/presentation/widgets/login.dart +++ b/lib/features/auth/presentation/widgets/login.dart @@ -10,11 +10,11 @@ class LoginForm extends StatefulWidget { class _LoginFormState extends State { TextStyle style = TextStyle(fontSize: 20.0); - TextEditingController _email; - TextEditingController _password; - FocusNode _passwordField; + TextEditingController? _email; + TextEditingController? _password; + FocusNode? _passwordField; final _formKey = GlobalKey(); - UserRepository user; + late UserRepository user; @override void initState() { @@ -38,9 +38,9 @@ class _LoginFormState extends State { key: Key("email-field"), controller: _email, validator: (value) => - (value.isEmpty) ? S.of(context).emailValidationError : null, + (value!.isEmpty) ? S.of(context)!.emailValidationError : null, decoration: InputDecoration( - labelText: S.of(context).emailFieldlabel, + labelText: S.of(context)!.emailFieldlabel, ), style: style, textInputAction: TextInputAction.next, @@ -58,9 +58,9 @@ class _LoginFormState extends State { controller: _password, obscureText: true, validator: (value) => - (value.isEmpty) ? S.of(context).passwordValidationError : null, + (value!.isEmpty) ? S.of(context)!.passwordValidationError : null, decoration: InputDecoration( - labelText: S.of(context).passwordFieldLabel, + labelText: S.of(context)!.passwordFieldLabel, ), style: style, onEditingComplete: _login, @@ -76,7 +76,7 @@ class _LoginFormState extends State { elevation: 0, highlightElevation: 0, onPressed: _login, - child: Text(S.of(context).loginButtonText), + child: Text(S.of(context)!.loginButtonText), ), ), ], @@ -85,18 +85,18 @@ class _LoginFormState extends State { } _login() async { - if (_formKey.currentState.validate()) { - if (!await user.signIn(_email.text, _password.text)) + if (_formKey.currentState!.validate()) { + if (!await user.signIn(_email!.text, _password!.text)) Scaffold.of(context).showSnackBar(SnackBar( - content: Text(user.error), + content: Text(user.error!), )); } } @override void dispose() { - _email.dispose(); - _password.dispose(); + _email!.dispose(); + _password!.dispose(); super.dispose(); } } diff --git a/lib/features/auth/presentation/widgets/signup.dart b/lib/features/auth/presentation/widgets/signup.dart index 91b3210..cffd71a 100644 --- a/lib/features/auth/presentation/widgets/signup.dart +++ b/lib/features/auth/presentation/widgets/signup.dart @@ -10,14 +10,14 @@ class SignupForm extends StatefulWidget { class _SignupFormState extends State { TextStyle style = TextStyle(fontSize: 20.0); - TextEditingController _email; - TextEditingController _password; - TextEditingController _confirmPassword; - FocusNode _passwordField; - FocusNode _confirmPasswordField; + TextEditingController? _email; + TextEditingController? _password; + TextEditingController? _confirmPassword; + FocusNode? _passwordField; + FocusNode? _confirmPasswordField; final _formKey = GlobalKey(); final _key = GlobalKey(); - UserRepository user; + late UserRepository user; @override void initState() { @@ -43,9 +43,9 @@ class _SignupFormState extends State { key: Key("email-field"), controller: _email, validator: (value) => - (value.isEmpty) ? S.of(context).emailValidationError : null, + (value!.isEmpty) ? S.of(context)!.emailValidationError : null, decoration: InputDecoration( - labelText: S.of(context).emailFieldlabel, + labelText: S.of(context)!.emailFieldlabel, ), style: style, textInputAction: TextInputAction.next, @@ -63,9 +63,9 @@ class _SignupFormState extends State { controller: _password, obscureText: true, validator: (value) => - (value.isEmpty) ? S.of(context).passwordValidationError : null, + (value!.isEmpty) ? S.of(context)!.passwordValidationError : null, decoration: InputDecoration( - labelText: S.of(context).passwordValidationError, + labelText: S.of(context)!.passwordValidationError, ), style: style, textInputAction: TextInputAction.next, @@ -81,13 +81,13 @@ class _SignupFormState extends State { key: Key("confirm-password-field"), controller: _confirmPassword, obscureText: true, - validator: (value) => (value.isEmpty) - ? S.of(context).confirmPasswordValidationEmptyError - : value.isNotEmpty && _password.text != _confirmPassword.text - ? S.of(context).confirmPasswordValidationMatchError + validator: (value) => (value!.isEmpty) + ? S.of(context)!.confirmPasswordValidationEmptyError + : value.isNotEmpty && _password!.text != _confirmPassword!.text + ? S.of(context)!.confirmPasswordValidationMatchError : null, decoration: InputDecoration( - labelText: S.of(context).confirmPasswordFieldLabel, + labelText: S.of(context)!.confirmPasswordFieldLabel, ), style: style, focusNode: _confirmPasswordField, @@ -103,7 +103,7 @@ class _SignupFormState extends State { elevation: 0, highlightElevation: 0, onPressed: _signup, - child: Text(S.of(context).signupButtonText), + child: Text(S.of(context)!.signupButtonText), ), ), ], @@ -112,19 +112,19 @@ class _SignupFormState extends State { } _signup() async { - if (_formKey.currentState.validate()) { + if (_formKey.currentState!.validate()) { //signup user - if (!await user.signup(_email.text, _password.text)) + if (!await user.signup(_email!.text, _password!.text)) Scaffold.of(context).showSnackBar(SnackBar( - content: Text(user.error), + content: Text(user.error!), )); } } @override void dispose() { - _email.dispose(); - _password.dispose(); + _email!.dispose(); + _password!.dispose(); super.dispose(); } } diff --git a/lib/features/notification/data/service/push_notification_service.dart b/lib/features/notification/data/service/push_notification_service.dart index 0e72963..af58316 100644 --- a/lib/features/notification/data/service/push_notification_service.dart +++ b/lib/features/notification/data/service/push_notification_service.dart @@ -6,13 +6,13 @@ import 'dart:developer' as dev; class PushNotificationService { final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance; bool initialized = false; - String token; + String? token; PushNotificationService(); FirebaseMessaging get firebaseMessaging => _firebaseMessaging; - Future init() async { + Future init() async { if (!initialized) { if (Platform.isIOS) { _requestPermission(); @@ -22,7 +22,7 @@ class PushNotificationService { return; }); - RemoteMessage message = await _firebaseMessaging.getInitialMessage(); + RemoteMessage? message = await _firebaseMessaging.getInitialMessage(); dev.log("notification onMessage", error: message, time: DateTime.now()); FirebaseMessaging.onMessageOpenedApp.listen((message) { diff --git a/lib/features/onboarding/presentation/pages/intro.dart b/lib/features/onboarding/presentation/pages/intro.dart index b8420d3..d87008d 100644 --- a/lib/features/onboarding/presentation/pages/intro.dart +++ b/lib/features/onboarding/presentation/pages/intro.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:flutter_swiper/flutter_swiper.dart'; +import 'package:flutter_swiper_null_safety/flutter_swiper_null_safety.dart'; import 'package:provider/provider.dart'; import 'package:firebasestarter/features/auth/data/model/user_repository.dart'; import 'package:firebasestarter/features/profile/data/model/user_field.dart'; @@ -21,7 +21,7 @@ class IntroPage extends StatelessWidget { onPressed: (){ _finishIntroScreen(context); }, - child: Text(S.of(context).introFinishButtonLabel), + child: Text(S.of(context)!.introFinishButtonLabel), ) ], ); @@ -31,7 +31,7 @@ class IntroPage extends StatelessWidget { } _finishIntroScreen(BuildContext context) async { - await userDBS.updateData(Provider.of(context,listen: false).user.id, { + await userDBS.updateData(Provider.of(context,listen: false).user!.id!, { UserFields.introSeen: true, }); } diff --git a/lib/features/profile/data/model/device.dart b/lib/features/profile/data/model/device.dart index 144746b..b4a6eb0 100644 --- a/lib/features/profile/data/model/device.dart +++ b/lib/features/profile/data/model/device.dart @@ -2,13 +2,13 @@ import 'package:firebase_helpers/firebase_helpers.dart'; import 'package:firebasestarter/features/profile/data/model/device_field.dart'; class Device{ - String id; - DateTime createdAt; - bool expired; - bool uninstalled; - int lastUpdatedAt; - DeviceDetails deviceInfo; - String token; + String? id; + DateTime? createdAt; + bool? expired; + bool? uninstalled; + int? lastUpdatedAt; + DeviceDetails? deviceInfo; + String? token; Device({this.id, this.token,this.createdAt,this.expired,this.uninstalled,this.lastUpdatedAt,this.deviceInfo}); @@ -24,7 +24,7 @@ class Device{ Map toMap() { return { DeviceFields.createdAt: createdAt, - DeviceFields.deviceInfo: deviceInfo.toJson(), + DeviceFields.deviceInfo: deviceInfo!.toJson(), DeviceFields.expired:expired, DeviceFields.uninstalled:uninstalled, DeviceFields.lastUpdatedAt: lastUpdatedAt, @@ -34,10 +34,10 @@ class Device{ } class DeviceDetails { - String device; - String model; - String osVersion; - String platform; + String? device; + String? model; + String? osVersion; + String? platform; DeviceDetails({this.device, this.model, this.osVersion, this.platform}); diff --git a/lib/features/profile/data/model/user.dart b/lib/features/profile/data/model/user.dart index 66a9bfe..944f55c 100644 --- a/lib/features/profile/data/model/user.dart +++ b/lib/features/profile/data/model/user.dart @@ -2,14 +2,14 @@ import 'package:firebase_helpers/firebase_helpers.dart'; import 'package:firebasestarter/features/profile/data/model/user_field.dart'; class UserModel { - String id; - String name; - String email; - DateTime lastLoggedIn; - DateTime registrationDate; - String photoUrl; - int buildNumber; - bool introSeen; + String? id; + String? name; + String? email; + DateTime? lastLoggedIn; + DateTime? registrationDate; + String? photoUrl; + int? buildNumber; + bool? introSeen; UserModel( {this.id, diff --git a/lib/features/profile/data/service/user_db_service.dart b/lib/features/profile/data/service/user_db_service.dart index 367e8c4..abd1e4d 100644 --- a/lib/features/profile/data/service/user_db_service.dart +++ b/lib/features/profile/data/service/user_db_service.dart @@ -7,7 +7,7 @@ import 'package:firebasestarter/features/profile/data/model/user.dart'; DatabaseService userDBS = DatabaseService( AppDBConstants.usersCollection, toMap: (user) => user.toMap(), - fromDS: (id, data) => UserModel.fromDS(id, data)); + fromDS: (id, data) => UserModel.fromDS(id, data!)); UserDeviceDBService userDeviceDBS = UserDeviceDBService("devices"); @@ -15,7 +15,7 @@ class UserDeviceDBService extends DatabaseService { String collection; UserDeviceDBService(this.collection) : super(collection, - fromDS: (id, data) => Device.fromDS(id, data), + fromDS: (id, data) => Device.fromDS(id, data!), toMap: (device) => device.toMap()); Stream> getAllModels() { diff --git a/lib/features/profile/presentation/pages/edit_profile.dart b/lib/features/profile/presentation/pages/edit_profile.dart index e2c0004..170e6ec 100644 --- a/lib/features/profile/presentation/pages/edit_profile.dart +++ b/lib/features/profile/presentation/pages/edit_profile.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:io'; import 'package:firebase_helpers/firebase_helpers.dart'; @@ -13,9 +14,9 @@ import 'package:firebasestarter/generated/l10n.dart'; import 'package:path/path.dart' as Path; class EditProfile extends StatefulWidget { - final UserModel user; + final UserModel? user; - const EditProfile({Key key, this.user}) : super(key: key); + const EditProfile({Key? key, this.user}) : super(key: key); @override _EditProfileState createState() => _EditProfileState(); @@ -28,25 +29,25 @@ enum AppState { } class _EditProfileState extends State { - TextEditingController _nameController; - bool _processing; - AppState state; - File _image; - String _uploadedFileURL; + TextEditingController? _nameController; + late bool _processing; + AppState? state; + File? _image; + String? _uploadedFileURL; @override void initState() { super.initState(); _processing = false; state = AppState.free; - _nameController = TextEditingController(text: widget.user.name); + _nameController = TextEditingController(text: widget.user!.name); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text(S.of(context).editProfile), + title: Text(S.of(context)!.editProfile), ), body: ListView( padding: const EdgeInsets.all(8.0), @@ -56,32 +57,32 @@ class _EditProfileState extends State { showButton: true, onButtonPressed: _pickImageButtonPressed, radius: 50, - image: state == AppState.cropped && _image != null - ? FileImage(_image) - : widget.user.photoUrl != null - ? NetworkImage(widget.user.photoUrl) - : null, + image: (state == AppState.cropped && _image != null + ? FileImage(_image!) + : widget.user!.photoUrl != null + ? NetworkImage(widget.user!.photoUrl!) + : null) as ImageProvider?, ), ), const SizedBox(height: 10.0), - Center(child: Text(widget.user.email)), + Center(child: Text(widget.user!.email!)), const SizedBox(height: 10.0), TextField( controller: _nameController, decoration: - InputDecoration(labelText: S.of(context).nameFieldLabel), + InputDecoration(labelText: S.of(context)!.nameFieldLabel), ), const SizedBox(height: 10.0), Center( child: RaisedButton( child: _processing ? CircularProgressIndicator() - : Text(S.of(context).saveButtonLabel), + : Text(S.of(context)!.saveButtonLabel), onPressed: _processing ? null : () async { //save name - if (_nameController.text.isEmpty && + if (_nameController!.text.isEmpty && (_image == null || state != AppState.cropped)) return; setState(() { _processing = true; @@ -90,12 +91,12 @@ class _EditProfileState extends State { await uploadImage(); } Map data = {}; - if (_nameController.text.isNotEmpty) - data[UserFields.name] = _nameController.text; + if (_nameController!.text.isNotEmpty) + data[UserFields.name] = _nameController!.text; if (_uploadedFileURL != null) data[UserFields.photoUrl] = _uploadedFileURL; if (data.isNotEmpty) { - await userDBS.updateData(widget.user.id, data); + await userDBS.updateData(widget.user!.id!, data); } if (mounted) { setState(() { @@ -117,7 +118,7 @@ class _EditProfileState extends State { builder: (BuildContext context) { return AlertDialog( title: Text( - S.of(context).pickImageDialogTitle, + S.of(context)!.pickImageDialogTitle, ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.0)), @@ -130,13 +131,13 @@ class _EditProfileState extends State { onTap: () { getImage(ImageSource.camera); }, - title: Text(S.of(context).pickFromCameraButtonLabel), + title: Text(S.of(context)!.pickFromCameraButtonLabel), ), ListTile( onTap: () { getImage(ImageSource.gallery); }, - title: Text(S.of(context).pickFromGalleryButtonLabel), + title: Text(S.of(context)!.pickFromGalleryButtonLabel), ), ],), FlatButton( @@ -144,7 +145,7 @@ class _EditProfileState extends State { Navigator.pop(context); }, child: Text( - S.of(context).cancelButtonLabel, + S.of(context)!.cancelButtonLabel, style: TextStyle(fontWeight: FontWeight.bold), ), ), @@ -166,8 +167,8 @@ class _EditProfileState extends State { } Future _cropImage() async { - File croppedFile = await ImageCropper.cropImage( - sourcePath: _image.path, + File? croppedFile = await ImageCropper.cropImage( + sourcePath: _image!.path, maxWidth: 800, aspectRatio: CropAspectRatio(ratioX: 1.0, ratioY: 1.0), ); @@ -181,8 +182,8 @@ class _EditProfileState extends State { Future uploadImage() async { String path = - '${AppDBConstants.usersStorageBucket}/${widget.user.id}/${Path.basename(_image.path)}'; - String url = await StorageService.instance.uploadFile(path, _image); + '${AppDBConstants.usersStorageBucket}/${widget.user!.id}/${Path.basename(_image!.path)}'; + String? url = await (StorageService.instance.uploadFile(path, _image!) as FutureOr); setState(() { _uploadedFileURL = url; }); diff --git a/lib/features/profile/presentation/pages/profile.dart b/lib/features/profile/presentation/pages/profile.dart index 415f2e3..0cb1fda 100644 --- a/lib/features/profile/presentation/pages/profile.dart +++ b/lib/features/profile/presentation/pages/profile.dart @@ -12,10 +12,10 @@ class UserProfile extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text(S.of(context).profilePageTitle), + title: Text(S.of(context)!.profilePageTitle), ), body: Consumer(builder: (context, userRepo, _) { - UserModel user = userRepo.user; + UserModel? user = userRepo.user; return ListView( padding: const EdgeInsets.all(8.0), children: [ @@ -25,28 +25,28 @@ class UserProfile extends StatelessWidget { onButtonPressed: () {}, radius: 50, image: user.photoUrl != null - ? NetworkImage(user.photoUrl) + ? NetworkImage(user.photoUrl!) : null, ), ), const SizedBox(height: 10.0), if(user.name != null) ...[ - Center(child: Text(user.name),), + Center(child: Text(user.name ?? "Unknown"),), const SizedBox(height: 5.0), ], - Center(child: Text(user?.email)), + Center(child: Text(user.email ?? "No Email")), ], ...ListTile.divideTiles( color: Theme.of(context).dividerColor, tiles: [ ListTile( leading: Icon(Icons.edit), - title: Text(S.of(context).editProfile), + title: Text(S.of(context)!.editProfile), onTap: () => Navigator.pushNamed(context, AppRoutes.editProfile,arguments: user), ), ListTile( leading: Icon(Icons.exit_to_app), - title: Text(S.of(context).logoutButtonText), + title: Text(S.of(context)!.logoutButtonText), onTap: () async { await logEvent(context, AppAnalyticsEvents.logOut); await Provider.of(context, listen: false) diff --git a/lib/features/profile/presentation/widgets/avatar.dart b/lib/features/profile/presentation/widgets/avatar.dart index 7146ee5..c8b9412 100644 --- a/lib/features/profile/presentation/widgets/avatar.dart +++ b/lib/features/profile/presentation/widgets/avatar.dart @@ -2,16 +2,16 @@ import 'package:flutter/material.dart'; import 'package:firebasestarter/core/presentation/res/colors.dart'; class Avatar extends StatelessWidget { - final ImageProvider image; - final Color borderColor; + final ImageProvider? image; + final Color? borderColor; final double radius; final double borderWidth; - final Function onButtonPressed; + final Function? onButtonPressed; final bool showButton; const Avatar( - {Key key, - @required this.image, + {Key? key, + required this.image, this.borderColor, this.radius = 30, this.onButtonPressed, @@ -30,7 +30,7 @@ class Avatar extends StatelessWidget { borderColor != null ? borderColor : AppColors.primaryColorLight, child: CircleAvatar( radius: radius - borderWidth, - backgroundImage: image, + backgroundImage: image as ImageProvider?, ), ), if(showButton) @@ -43,7 +43,7 @@ class Avatar extends StatelessWidget { shape: CircleBorder(), child: Icon(Icons.camera_alt), padding: const EdgeInsets.all(4.0), - onPressed: onButtonPressed, + onPressed: onButtonPressed as void Function()?, ), ) ], diff --git a/lib/generated/intl/messages_all.dart b/lib/generated/intl/messages_all.dart index b285749..a6e6b20 100644 --- a/lib/generated/intl/messages_all.dart +++ b/lib/generated/intl/messages_all.dart @@ -22,7 +22,7 @@ Map _deferredLibraries = { 'en': () => new Future.value(null), }; -MessageLookupByLibrary _findExact(String localeName) { +MessageLookupByLibrary? _findExact(String localeName) { switch (localeName) { case 'en': return messages_en.messages; @@ -55,7 +55,7 @@ bool _messagesExistFor(String locale) { } } -MessageLookupByLibrary _findGeneratedMessagesFor(String locale) { +MessageLookupByLibrary? _findGeneratedMessagesFor(String locale) { var actualLocale = Intl.verifiedLocale(locale, _messagesExistFor, onFailure: (_) => null); if (actualLocale == null) return null; diff --git a/lib/generated/intl/messages_en.dart b/lib/generated/intl/messages_en.dart index ce632df..c2e24bd 100644 --- a/lib/generated/intl/messages_en.dart +++ b/lib/generated/intl/messages_en.dart @@ -19,7 +19,7 @@ typedef String MessageIfAbsent(String messageStr, List args); class MessageLookup extends MessageLookupByLibrary { String get localeName => 'en'; - final messages = _notInlinedMessages(_notInlinedMessages); + final Map messages = _notInlinedMessages(_notInlinedMessages); static _notInlinedMessages(_) => { "appName" : MessageLookupByLibrary.simpleMessage("Firebase starter"), "cancelButtonLabel" : MessageLookupByLibrary.simpleMessage("Cancel"), diff --git a/lib/generated/l10n.dart b/lib/generated/l10n.dart index 73b6d78..940ed2e 100644 --- a/lib/generated/l10n.dart +++ b/lib/generated/l10n.dart @@ -15,7 +15,7 @@ import 'intl/messages_all.dart'; class S { S(); - static S current; + static late S current; static const AppLocalizationDelegate delegate = AppLocalizationDelegate(); @@ -31,7 +31,7 @@ class S { }); } - static S of(BuildContext context) { + static S? of(BuildContext context) { return Localizations.of(context, S); } diff --git a/pubspec.lock b/pubspec.lock index 8c0050c..f872a84 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,41 +1,34 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: - _fe_analyzer_shared: - dependency: transitive - description: - name: _fe_analyzer_shared - url: "https://pub.dartlang.org" - source: hosted - version: "7.0.0" - analyzer: - dependency: transitive - description: - name: analyzer - url: "https://pub.dartlang.org" - source: hosted - version: "0.39.17" archive: dependency: transitive description: name: archive url: "https://pub.dartlang.org" source: hosted - version: "2.0.13" + version: "3.1.2" args: dependency: transitive description: name: args url: "https://pub.dartlang.org" source: hosted - version: "1.6.0" + version: "2.2.0" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.5.0" + version: "2.6.1" + auth_buttons: + dependency: "direct main" + description: + name: auth_buttons + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1+4" boolean_selector: dependency: transitive description: @@ -64,13 +57,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" - cli_util: - dependency: transitive - description: - name: cli_util - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0" clock: dependency: transitive description: @@ -84,21 +70,21 @@ packages: name: cloud_firestore url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "2.4.0" cloud_firestore_platform_interface: dependency: transitive description: name: cloud_firestore_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "4.0.1" + version: "5.3.0" cloud_firestore_web: dependency: transitive description: name: cloud_firestore_web url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "2.3.0" collection: dependency: transitive description: @@ -106,41 +92,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.15.0" - convert: + cross_file: dependency: transitive description: - name: convert + name: cross_file url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "0.3.1+4" crypto: - dependency: "direct overridden" + dependency: transitive description: name: crypto url: "https://pub.dartlang.org" source: hosted version: "3.0.1" - csslib: - dependency: transitive - description: - name: csslib - url: "https://pub.dartlang.org" - source: hosted - version: "0.16.2" - dart_style: - dependency: transitive - description: - name: dart_style - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.6" device_info: dependency: "direct main" description: name: device_info url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.0.2" device_info_platform_interface: dependency: transitive description: @@ -161,14 +133,14 @@ packages: name: ffi url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "1.1.2" file: dependency: transitive description: name: file url: "https://pub.dartlang.org" source: hosted - version: "6.0.0" + version: "6.1.0" firebase: dependency: transitive description: @@ -182,159 +154,152 @@ packages: name: firebase_analytics url: "https://pub.dartlang.org" source: hosted - version: "7.1.1" + version: "8.2.0" firebase_analytics_platform_interface: dependency: transitive description: name: firebase_analytics_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "2.0.1" firebase_analytics_web: dependency: transitive description: name: firebase_analytics_web url: "https://pub.dartlang.org" source: hosted - version: "0.2.0+1" + version: "0.3.0+1" firebase_auth: dependency: "direct main" description: name: firebase_auth url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "3.0.1" firebase_auth_platform_interface: dependency: transitive description: name: firebase_auth_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "4.1.0" + version: "6.0.0" firebase_auth_web: dependency: transitive description: name: firebase_auth_web url: "https://pub.dartlang.org" source: hosted - version: "1.0.6" + version: "3.0.0" firebase_core: dependency: "direct main" description: name: firebase_core url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "1.4.0" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "4.0.0" + version: "4.0.1" firebase_core_web: dependency: transitive description: name: firebase_core_web url: "https://pub.dartlang.org" source: hosted - version: "1.0.2" + version: "1.1.0" firebase_crashlytics: dependency: "direct main" description: name: firebase_crashlytics url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.1" firebase_crashlytics_platform_interface: dependency: transitive description: name: firebase_crashlytics_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "3.0.0" + version: "3.1.0" firebase_helpers: dependency: "direct main" description: name: firebase_helpers url: "https://pub.dartlang.org" source: hosted - version: "0.3.1" + version: "0.4.0" firebase_messaging: dependency: "direct main" description: name: firebase_messaging url: "https://pub.dartlang.org" source: hosted - version: "9.1.1" + version: "10.0.4" firebase_messaging_platform_interface: dependency: transitive description: name: firebase_messaging_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "3.0.3" firebase_messaging_web: dependency: transitive description: name: firebase_messaging_web url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "2.0.3" firebase_remote_config: dependency: "direct main" description: name: firebase_remote_config url: "https://pub.dartlang.org" source: hosted - version: "0.9.0-dev.2" + version: "0.10.0+3" firebase_remote_config_platform_interface: dependency: transitive description: name: firebase_remote_config_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "0.2.0-dev.1" + version: "0.3.0+3" firebase_storage: dependency: "direct main" description: name: firebase_storage url: "https://pub.dartlang.org" source: hosted - version: "8.0.3" + version: "8.1.3" firebase_storage_platform_interface: dependency: transitive description: name: firebase_storage_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "2.1.2" firebase_storage_web: dependency: transitive description: name: firebase_storage_web url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "1.1.2" flutter: dependency: "direct main" description: flutter source: sdk version: "0.0.0" - flutter_auth_buttons: - dependency: "direct main" - description: - name: flutter_auth_buttons - url: "https://pub.dartlang.org" - source: hosted - version: "0.9.0" flutter_automation: dependency: "direct dev" description: name: flutter_automation url: "https://pub.dartlang.org" source: hosted - version: "1.4.0" + version: "2.0.0" flutter_driver: dependency: transitive description: flutter @@ -345,34 +310,27 @@ packages: description: flutter source: sdk version: "0.0.0" - flutter_page_indicator: - dependency: transitive - description: - name: flutter_page_indicator - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.3" flutter_plugin_android_lifecycle: dependency: transitive description: name: flutter_plugin_android_lifecycle url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "2.0.2" flutter_svg: dependency: "direct main" description: name: flutter_svg url: "https://pub.dartlang.org" source: hosted - version: "0.21.0+1" - flutter_swiper: + version: "0.22.0" + flutter_swiper_null_safety: dependency: "direct main" description: - name: flutter_swiper + name: flutter_swiper_null_safety url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.0.2" flutter_test: dependency: "direct dev" description: flutter @@ -388,27 +346,20 @@ packages: description: flutter source: sdk version: "0.0.0" - glob: - dependency: transitive - description: - name: glob - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" google_fonts: dependency: "direct main" description: name: google_fonts url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0" google_sign_in: dependency: "direct main" description: name: google_sign_in url: "https://pub.dartlang.org" source: hosted - version: "5.0.1" + version: "5.0.7" google_sign_in_platform_interface: dependency: transitive description: @@ -422,21 +373,14 @@ packages: name: google_sign_in_web url: "https://pub.dartlang.org" source: hosted - version: "0.10.0" - html: - dependency: transitive - description: - name: html - url: "https://pub.dartlang.org" - source: hosted - version: "0.14.0+3" + version: "0.10.0+1" http: - dependency: "direct overridden" + dependency: transitive description: name: http url: "https://pub.dartlang.org" source: hosted - version: "0.13.1" + version: "0.13.3" http_parser: dependency: transitive description: @@ -450,49 +394,40 @@ packages: name: image_cropper url: "https://pub.dartlang.org" source: hosted - version: "1.4.0" + version: "1.4.1" image_picker: dependency: "direct main" description: name: image_picker url: "https://pub.dartlang.org" source: hosted - version: "0.7.4" + version: "0.8.3+2" image_picker_for_web: dependency: transitive description: name: image_picker_for_web url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.2" image_picker_platform_interface: dependency: transitive description: name: image_picker_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.2.0" integration_test: dependency: "direct dev" - description: - name: integration_test - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2+2" + description: flutter + source: sdk + version: "0.0.0" intl: - dependency: "direct overridden" + dependency: transitive description: name: intl url: "https://pub.dartlang.org" source: hosted version: "0.17.0" - intl_translation: - dependency: "direct dev" - description: - name: intl_translation - url: "https://pub.dartlang.org" - source: hosted - version: "0.17.10+1" js: dependency: transitive description: @@ -521,34 +456,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.0" - node_interop: - dependency: transitive - description: - name: node_interop - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - node_io: - dependency: transitive - description: - name: node_io - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - package_config: - dependency: transitive - description: - name: package_config - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" package_info: dependency: "direct main" description: name: package_info url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.0.2" path: dependency: transitive description: @@ -562,35 +476,35 @@ packages: name: path_drawing url: "https://pub.dartlang.org" source: hosted - version: "0.5.0" + version: "0.5.1" path_parsing: dependency: transitive description: name: path_parsing url: "https://pub.dartlang.org" source: hosted - version: "0.2.0" + version: "0.2.1" path_provider: dependency: transitive description: name: path_provider url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "2.0.2" path_provider_linux: dependency: transitive description: name: path_provider_linux url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.0.2" path_provider_macos: dependency: transitive description: name: path_provider_macos url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.0.2" path_provider_platform_interface: dependency: transitive description: @@ -604,16 +518,16 @@ packages: name: path_provider_windows url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.0.3" pedantic: dependency: transitive description: name: pedantic url: "https://pub.dartlang.org" source: hosted - version: "1.11.0" + version: "1.11.1" petitparser: - dependency: "direct overridden" + dependency: transitive description: name: petitparser url: "https://pub.dartlang.org" @@ -632,14 +546,14 @@ packages: name: plugin_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.0.1" process: dependency: transitive description: name: process url: "https://pub.dartlang.org" source: hosted - version: "4.0.0" + version: "4.2.1" provider: dependency: "direct main" description: @@ -647,13 +561,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "5.0.0" - pub_semver: - dependency: transitive - description: - name: pub_semver - url: "https://pub.dartlang.org" - source: hosted - version: "1.4.4" quiver: dependency: transitive description: @@ -672,7 +579,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.0" + version: "1.8.1" stack_trace: dependency: transitive description: @@ -700,7 +607,7 @@ packages: name: sync_http url: "https://pub.dartlang.org" source: hosted - version: "0.2.0" + version: "0.3.0" term_glyph: dependency: transitive description: @@ -714,14 +621,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.19" - transformer_page_view: - dependency: transitive - description: - name: transformer_page_view - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.6" + version: "0.3.0" typed_data: dependency: transitive description: @@ -742,28 +642,21 @@ packages: name: vm_service url: "https://pub.dartlang.org" source: hosted - version: "5.5.0" - watcher: - dependency: transitive - description: - name: watcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.9.7+15" + version: "6.2.0" webdriver: dependency: transitive description: name: webdriver url: "https://pub.dartlang.org" source: hosted - version: "2.1.2" + version: "3.0.0" win32: dependency: transitive description: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "2.0.5" + version: "2.2.5" xdg_directories: dependency: transitive description: @@ -777,14 +670,14 @@ packages: name: xml url: "https://pub.dartlang.org" source: hosted - version: "5.1.0" + version: "5.1.2" yaml: dependency: transitive description: name: yaml url: "https://pub.dartlang.org" source: hosted - version: "2.2.1" + version: "3.1.0" sdks: - dart: ">=2.12.0 <3.0.0" - flutter: ">=1.24.0-7.0" + dart: ">=2.13.0 <3.0.0" + flutter: ">=2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index aa85940..e9df34b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,48 +3,40 @@ description: A new Flutter project. version: 1.0.0+1 environment: - sdk: ">=2.2.2 <3.0.0" + sdk: '>=2.12.0 <3.0.0' dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter - cloud_firestore: ^1.0.4 - device_info: ^2.0.0 - firebase_analytics: ^7.1.1 - firebase_auth: ^1.1.0 - firebase_core: ^1.0.3 - firebase_crashlytics: ^2.0.0 - firebase_helpers: ^0.3.1 - firebase_messaging: ^9.1.1 - firebase_remote_config: ^0.9.0-dev.2 - firebase_storage: ^8.0.3 - flutter_auth_buttons: ^0.9.0 - flutter_svg: ^0.21.0+1 - flutter_swiper: ^1.1.6 - google_fonts: ^2.0.0 - google_sign_in: ^5.0.1 - image_cropper: ^1.4.0 - image_picker: ^0.7.4 - package_info: ^2.0.0 + cloud_firestore: ^2.4.0 + device_info: ^2.0.2 + firebase_analytics: ^8.2.0 + firebase_auth: ^3.0.1 + firebase_core: ^1.4.0 + firebase_crashlytics: ^2.1.1 + firebase_helpers: ^0.4.0 + firebase_messaging: ^10.0.4 + firebase_remote_config: ^0.10.0+3 + firebase_storage: ^8.1.3 + flutter_svg: ^0.22.0 + google_fonts: ^2.1.0 + google_sign_in: ^5.0.7 + image_cropper: ^1.4.1 + image_picker: ^0.8.3+2 + package_info: ^2.0.2 provider: ^5.0.0 - -dependency_overrides: - crypto: ^3.0.0 - http: ^0.13.0 - intl: 0.17.0 - petitparser: ^4.1.0 + flutter_swiper_null_safety: ^1.0.2 + auth_buttons: ^1.0.1+4 dev_dependencies: flutter_test: sdk: flutter change_app_package_name: ^1.0.0 - flutter_automation: ^1.4.0 - integration_test: ^1.0.2+2 - intl_translation: ^0.17.10+1 + flutter_automation: ^2.0.0 + integration_test: + sdk: flutter flutter: uses-material-design: true -flutter_intl: - enabled: true diff --git a/test/widget_test.dart b/test/widget_test.dart index 15ddca7..ae5f7cd 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -8,12 +8,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:firebasestarter/main.dart'; +import 'package:firebasestarter/app.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); + await tester.pumpWidget(App()); // Verify that our counter starts at 0. expect(find.text('0'), findsOneWidget); From a967b558420ea55ff4a07c22ea57d4f7b6d5e77f Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Fri, 13 Aug 2021 19:22:35 +0545 Subject: [PATCH 3/4] fix errors and refactor --- .../auth/data/model/user_repository.dart | 8 +++++++- .../onboarding/presentation/pages/intro.dart | 5 ++--- .../profile/presentation/pages/edit_profile.dart | 16 +++++++++------- pubspec.lock | 7 ------- pubspec.yaml | 1 - 5 files changed, 18 insertions(+), 19 deletions(-) diff --git a/lib/features/auth/data/model/user_repository.dart b/lib/features/auth/data/model/user_repository.dart index 1931d78..cf1a547 100644 --- a/lib/features/auth/data/model/user_repository.dart +++ b/lib/features/auth/data/model/user_repository.dart @@ -77,7 +77,13 @@ class UserRepository with ChangeNotifier { try { _status = Status.Authenticating; notifyListeners(); - final GoogleSignInAccount googleUser = await (_googleSignIn.signIn() as FutureOr); + final GoogleSignInAccount? googleUser = await (_googleSignIn.signIn()); + if(googleUser == null) { + _error = 'Google sign in failed'; + _status = Status.Unauthenticated; + notifyListeners(); + return false; + } final GoogleSignInAuthentication googleAuth = await googleUser.authentication; final GoogleAuthCredential credential = GoogleAuthProvider.credential( diff --git a/lib/features/onboarding/presentation/pages/intro.dart b/lib/features/onboarding/presentation/pages/intro.dart index d87008d..1bdfc47 100644 --- a/lib/features/onboarding/presentation/pages/intro.dart +++ b/lib/features/onboarding/presentation/pages/intro.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter_swiper_null_safety/flutter_swiper_null_safety.dart'; import 'package:provider/provider.dart'; import 'package:firebasestarter/features/auth/data/model/user_repository.dart'; import 'package:firebasestarter/features/profile/data/model/user_field.dart'; @@ -10,14 +9,14 @@ class IntroPage extends StatelessWidget { @override Widget build(BuildContext context){ return Scaffold( - body: Swiper( + body: PageView.builder( itemCount: 1, itemBuilder: (context,index){ return Column( children: [ //implement intro screen Spacer(), - RaisedButton( + ElevatedButton( onPressed: (){ _finishIntroScreen(context); }, diff --git a/lib/features/profile/presentation/pages/edit_profile.dart b/lib/features/profile/presentation/pages/edit_profile.dart index 170e6ec..698e0f6 100644 --- a/lib/features/profile/presentation/pages/edit_profile.dart +++ b/lib/features/profile/presentation/pages/edit_profile.dart @@ -125,8 +125,9 @@ class _EditProfileState extends State { content: Column( mainAxisSize: MainAxisSize.min, children: [ - ...ListTile.divideTiles(color: Theme.of(context).dividerColor,tiles: [ - + ...ListTile.divideTiles( + color: Theme.of(context).dividerColor, + tiles: [ ListTile( onTap: () { getImage(ImageSource.camera); @@ -139,7 +140,8 @@ class _EditProfileState extends State { }, title: Text(S.of(context)!.pickFromGalleryButtonLabel), ), - ],), + ], + ), FlatButton( onPressed: () { Navigator.pop(context); @@ -156,9 +158,8 @@ class _EditProfileState extends State { } Future getImage(ImageSource source) async { - var image = await ImagePicker().getImage( - source: source); - if(image == null) return; + var image = await ImagePicker().getImage(source: source); + if (image == null) return; setState(() { _image = File(image.path); _cropImage(); @@ -183,7 +184,8 @@ class _EditProfileState extends State { Future uploadImage() async { String path = '${AppDBConstants.usersStorageBucket}/${widget.user!.id}/${Path.basename(_image!.path)}'; - String? url = await (StorageService.instance.uploadFile(path, _image!) as FutureOr); + String? url = + (await StorageService.instance.uploadFile(path, _image!)).toString(); setState(() { _uploadedFileURL = url; }); diff --git a/pubspec.lock b/pubspec.lock index f872a84..b044bb2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -324,13 +324,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.22.0" - flutter_swiper_null_safety: - dependency: "direct main" - description: - name: flutter_swiper_null_safety - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" flutter_test: dependency: "direct dev" description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index e9df34b..c6db5fb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -27,7 +27,6 @@ dependencies: image_picker: ^0.8.3+2 package_info: ^2.0.2 provider: ^5.0.0 - flutter_swiper_null_safety: ^1.0.2 auth_buttons: ^1.0.1+4 dev_dependencies: From 2946afd793605a56a064aec060d4788e2309494c Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Fri, 13 Aug 2021 19:55:26 +0545 Subject: [PATCH 4/4] web support and some fixes --- .../auth/data/model/user_repository.dart | 41 +++--- .../auth/presentation/pages/login.dart | 2 +- web/favicon.png | Bin 0 -> 917 bytes web/icons/Icon-192.png | Bin 0 -> 5292 bytes web/icons/Icon-512.png | Bin 0 -> 8252 bytes web/index.html | 125 ++++++++++++++++++ web/manifest.json | 23 ++++ 7 files changed, 175 insertions(+), 16 deletions(-) create mode 100644 web/favicon.png create mode 100644 web/icons/Icon-192.png create mode 100644 web/icons/Icon-512.png create mode 100644 web/index.html create mode 100644 web/manifest.json diff --git a/lib/features/auth/data/model/user_repository.dart b/lib/features/auth/data/model/user_repository.dart index cf1a547..3d2f6b0 100644 --- a/lib/features/auth/data/model/user_repository.dart +++ b/lib/features/auth/data/model/user_repository.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:io'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:device_info/device_info.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:google_sign_in/google_sign_in.dart'; @@ -77,20 +78,25 @@ class UserRepository with ChangeNotifier { try { _status = Status.Authenticating; notifyListeners(); - final GoogleSignInAccount? googleUser = await (_googleSignIn.signIn()); - if(googleUser == null) { - _error = 'Google sign in failed'; - _status = Status.Unauthenticated; - notifyListeners(); - return false; + if (kIsWeb) { + GoogleAuthProvider googleProvider = GoogleAuthProvider(); + await _auth.signInWithPopup(googleProvider); + } else { + final GoogleSignInAccount? googleUser = await (_googleSignIn.signIn()); + if (googleUser == null) { + _error = 'Google sign in failed'; + _status = Status.Unauthenticated; + notifyListeners(); + return false; + } + final GoogleSignInAuthentication googleAuth = + await googleUser.authentication; + final GoogleAuthCredential credential = GoogleAuthProvider.credential( + accessToken: googleAuth.accessToken, + idToken: googleAuth.idToken, + ) as GoogleAuthCredential; + await _auth.signInWithCredential(credential); } - final GoogleSignInAuthentication googleAuth = - await googleUser.authentication; - final GoogleAuthCredential credential = GoogleAuthProvider.credential( - accessToken: googleAuth.accessToken, - idToken: googleAuth.idToken, - ) as GoogleAuthCredential; - await _auth.signInWithCredential(credential); _error = ''; return true; } catch (e) { @@ -131,8 +137,13 @@ class UserRepository with ChangeNotifier { Future _saveUserRecord() async { if (_user == null) return; - PackageInfo packageInfo = await PackageInfo.fromPlatform(); - int buildNumber = int.parse(packageInfo.buildNumber); + int buildNumber; + if (kIsWeb) { + buildNumber = 1; + } else { + PackageInfo packageInfo = await PackageInfo.fromPlatform(); + buildNumber = int.parse(packageInfo.buildNumber); + } UserModel user = UserModel( email: _user!.email, name: _user!.displayName, diff --git a/lib/features/auth/presentation/pages/login.dart b/lib/features/auth/presentation/pages/login.dart index cb4530f..055490b 100644 --- a/lib/features/auth/presentation/pages/login.dart +++ b/lib/features/auth/presentation/pages/login.dart @@ -87,7 +87,7 @@ class _WelcomePageState extends State { onPressed: () async { if (!await user.signInWithGoogle()) _key.currentState!.showSnackBar(SnackBar( - content: Text("Something is wrong"), + content: Text(user.error!), )); }, ), diff --git a/web/favicon.png b/web/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..8aaa46ac1ae21512746f852a42ba87e4165dfdd1 GIT binary patch literal 917 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|I14-?iy0X7 zltGxWVyS%@P(fs7NJL45ua8x7ey(0(N`6wRUPW#JP&EUCO@$SZnVVXYs8ErclUHn2 zVXFjIVFhG^g!Ppaz)DK8ZIvQ?0~DO|i&7O#^-S~(l1AfjnEK zjFOT9D}DX)@^Za$W4-*MbbUihOG|wNBYh(yU7!lx;>x^|#0uTKVr7USFmqf|i<65o z3raHc^AtelCMM;Vme?vOfh>Xph&xL%(-1c06+^uR^q@XSM&D4+Kp$>4P^%3{)XKjo zGZknv$b36P8?Z_gF{nK@`XI}Z90TzwSQO}0J1!f2c(B=V`5aP@1P1a|PZ!4!3&Gl8 zTYqUsf!gYFyJnXpu0!n&N*SYAX-%d(5gVjrHJWqXQshj@!Zm{!01WsQrH~9=kTxW#6SvuapgMqt>$=j#%eyGrQzr zP{L-3gsMA^$I1&gsBAEL+vxi1*Igl=8#8`5?A-T5=z-sk46WA1IUT)AIZHx1rdUrf zVJrJn<74DDw`j)Ki#gt}mIT-Q`XRa2-jQXQoI%w`nb|XblvzK${ZzlV)m-XcwC(od z71_OEC5Bt9GEXosOXaPTYOia#R4ID2TiU~`zVMl08TV_C%DnU4^+HE>9(CE4D6?Fz oujB08i7adh9xk7*FX66dWH6F5TM;?E2b5PlUHx3vIVCg!0Dx9vYXATM literal 0 HcmV?d00001 diff --git a/web/icons/Icon-192.png b/web/icons/Icon-192.png new file mode 100644 index 0000000000000000000000000000000000000000..b749bfef07473333cf1dd31e9eed89862a5d52aa GIT binary patch literal 5292 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 literal 0 HcmV?d00001 diff --git a/web/icons/Icon-512.png b/web/icons/Icon-512.png new file mode 100644 index 0000000000000000000000000000000000000000..88cfd48dff1169879ba46840804b412fe02fefd6 GIT binary patch literal 8252 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 literal 0 HcmV?d00001 diff --git a/web/index.html b/web/index.html new file mode 100644 index 0000000..b8473e9 --- /dev/null +++ b/web/index.html @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + flutter_firebase_starter + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/web/manifest.json b/web/manifest.json new file mode 100644 index 0000000..66a8cf8 --- /dev/null +++ b/web/manifest.json @@ -0,0 +1,23 @@ +{ + "name": "flutter_firebase_starter", + "short_name": "flutter_firebase_starter", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + } + ] +}