From 70ad23e9ec8e95e70552d8468fdd4335263a64e0 Mon Sep 17 00:00:00 2001 From: noblebuildsai Date: Thu, 5 Feb 2026 11:41:41 +0530 Subject: [PATCH] chore: update dependencies for Firebase Auth 6.x and google_sign_in 7.x - Update firebase_core, firebase_auth, firebase_auth_platform_interface - Update google_sign_in, sign_in_with_apple, flutter_facebook_auth - Update logger, crypto, flutter_lints, stacked packages Firebase Auth 6.x: replace deprecated APIs (fetchSignInMethodsForEmail, updateEmail) google_sign_in 7.x: migrate to new authenticate/authorizationForScopes API flutter_facebook_auth 7.x: use tokenString instead of token Add FirebaseAuthenticationService mock to example tests --- example/lib/app/app.bottomsheets.dart | 1 + example/lib/app/app.dialogs.dart | 1 + example/lib/app/app.locator.dart | 1 + example/lib/app/app.router.dart | 211 +++-- example/pubspec.yaml | 14 +- example/test/helpers/test_helpers.dart | 10 + example/test/helpers/test_helpers.mocks.dart | 788 ++++++++++++++++--- lib/src/firebase_authentication_service.dart | 55 +- pubspec.yaml | 20 +- 9 files changed, 908 insertions(+), 193 deletions(-) diff --git a/example/lib/app/app.bottomsheets.dart b/example/lib/app/app.bottomsheets.dart index 777004c..963d080 100644 --- a/example/lib/app/app.bottomsheets.dart +++ b/example/lib/app/app.bottomsheets.dart @@ -1,3 +1,4 @@ +// dart format width=80 // GENERATED CODE - DO NOT MODIFY BY HAND // ************************************************************************** diff --git a/example/lib/app/app.dialogs.dart b/example/lib/app/app.dialogs.dart index 2a4e944..17d0a0e 100644 --- a/example/lib/app/app.dialogs.dart +++ b/example/lib/app/app.dialogs.dart @@ -1,3 +1,4 @@ +// dart format width=80 // GENERATED CODE - DO NOT MODIFY BY HAND // ************************************************************************** diff --git a/example/lib/app/app.locator.dart b/example/lib/app/app.locator.dart index 8cd3323..39da533 100644 --- a/example/lib/app/app.locator.dart +++ b/example/lib/app/app.locator.dart @@ -1,3 +1,4 @@ +// dart format width=80 // GENERATED CODE - DO NOT MODIFY BY HAND // ************************************************************************** diff --git a/example/lib/app/app.router.dart b/example/lib/app/app.router.dart index b414a02..f31457c 100644 --- a/example/lib/app/app.router.dart +++ b/example/lib/app/app.router.dart @@ -1,3 +1,4 @@ +// dart format width=80 // GENERATED CODE - DO NOT MODIFY BY HAND // ************************************************************************** @@ -20,45 +21,41 @@ class Routes { static const securedAreaView = '/secured-area-view'; - static const all = { - homeView, - startupView, - securedAreaView, - }; + static const all = {homeView, startupView, securedAreaView}; } class StackedRouter extends _i1.RouterBase { final _routes = <_i1.RouteDef>[ - _i1.RouteDef( - Routes.homeView, - page: _i2.HomeView, - ), - _i1.RouteDef( - Routes.startupView, - page: _i3.StartupView, - ), - _i1.RouteDef( - Routes.securedAreaView, - page: _i4.SecuredAreaView, - ), + _i1.RouteDef(Routes.homeView, page: _i2.HomeView), + _i1.RouteDef(Routes.startupView, page: _i3.StartupView), + _i1.RouteDef(Routes.securedAreaView, page: _i4.SecuredAreaView), ]; final _pagesMap = { _i2.HomeView: (data) { + final args = data.getArgs( + orElse: () => const HomeViewArguments(), + ); return _i5.MaterialPageRoute( - builder: (context) => const _i2.HomeView(), + builder: (context) => _i2.HomeView(key: args.key), settings: data, ); }, _i3.StartupView: (data) { + final args = data.getArgs( + orElse: () => const StartupViewArguments(), + ); return _i5.MaterialPageRoute( - builder: (context) => const _i3.StartupView(), + builder: (context) => _i3.StartupView(key: args.key), settings: data, ); }, _i4.SecuredAreaView: (data) { + final args = data.getArgs( + orElse: () => const SecuredAreaViewArguments(), + ); return _i5.MaterialPageRoute( - builder: (context) => const _i4.SecuredAreaView(), + builder: (context) => _i4.SecuredAreaView(key: args.key), settings: data, ); }, @@ -71,88 +68,178 @@ class StackedRouter extends _i1.RouterBase { Map get pagesMap => _pagesMap; } +class HomeViewArguments { + const HomeViewArguments({this.key}); + + final _i5.Key? key; + + @override + String toString() { + return '{"key": "$key"}'; + } + + @override + bool operator ==(covariant HomeViewArguments other) { + if (identical(this, other)) return true; + return other.key == key; + } + + @override + int get hashCode { + return key.hashCode; + } +} + +class StartupViewArguments { + const StartupViewArguments({this.key}); + + final _i5.Key? key; + + @override + String toString() { + return '{"key": "$key"}'; + } + + @override + bool operator ==(covariant StartupViewArguments other) { + if (identical(this, other)) return true; + return other.key == key; + } + + @override + int get hashCode { + return key.hashCode; + } +} + +class SecuredAreaViewArguments { + const SecuredAreaViewArguments({this.key}); + + final _i5.Key? key; + + @override + String toString() { + return '{"key": "$key"}'; + } + + @override + bool operator ==(covariant SecuredAreaViewArguments other) { + if (identical(this, other)) return true; + return other.key == key; + } + + @override + int get hashCode { + return key.hashCode; + } +} + extension NavigatorStateExtension on _i6.NavigationService { - Future navigateToHomeView([ + Future navigateToHomeView({ + _i5.Key? key, int? routerId, bool preventDuplicates = true, Map? parameters, Widget Function(BuildContext, Animation, Animation, Widget)? transition, - ]) async { - return navigateTo(Routes.homeView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); + }) async { + return navigateTo( + Routes.homeView, + arguments: HomeViewArguments(key: key), + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition, + ); } - Future navigateToStartupView([ + Future navigateToStartupView({ + _i5.Key? key, int? routerId, bool preventDuplicates = true, Map? parameters, Widget Function(BuildContext, Animation, Animation, Widget)? transition, - ]) async { - return navigateTo(Routes.startupView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); + }) async { + return navigateTo( + Routes.startupView, + arguments: StartupViewArguments(key: key), + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition, + ); } - Future navigateToSecuredAreaView([ + Future navigateToSecuredAreaView({ + _i5.Key? key, int? routerId, bool preventDuplicates = true, Map? parameters, Widget Function(BuildContext, Animation, Animation, Widget)? transition, - ]) async { - return navigateTo(Routes.securedAreaView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); + }) async { + return navigateTo( + Routes.securedAreaView, + arguments: SecuredAreaViewArguments(key: key), + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition, + ); } - Future replaceWithHomeView([ + Future replaceWithHomeView({ + _i5.Key? key, int? routerId, bool preventDuplicates = true, Map? parameters, Widget Function(BuildContext, Animation, Animation, Widget)? transition, - ]) async { - return replaceWith(Routes.homeView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); + }) async { + return replaceWith( + Routes.homeView, + arguments: HomeViewArguments(key: key), + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition, + ); } - Future replaceWithStartupView([ + Future replaceWithStartupView({ + _i5.Key? key, int? routerId, bool preventDuplicates = true, Map? parameters, Widget Function(BuildContext, Animation, Animation, Widget)? transition, - ]) async { - return replaceWith(Routes.startupView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); + }) async { + return replaceWith( + Routes.startupView, + arguments: StartupViewArguments(key: key), + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition, + ); } - Future replaceWithSecuredAreaView([ + Future replaceWithSecuredAreaView({ + _i5.Key? key, int? routerId, bool preventDuplicates = true, Map? parameters, Widget Function(BuildContext, Animation, Animation, Widget)? transition, - ]) async { - return replaceWith(Routes.securedAreaView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); + }) async { + return replaceWith( + Routes.securedAreaView, + arguments: SecuredAreaViewArguments(key: key), + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition, + ); } } diff --git a/example/pubspec.yaml b/example/pubspec.yaml index b86d897..bc689e3 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -9,19 +9,19 @@ environment: dependencies: flutter: sdk: flutter - stacked: ^3.4.0 - stacked_services: ^1.1.0 - firebase_core: ^3.4.0 + stacked: ^3.5.0 + stacked_services: ^1.6.0 + firebase_core: ^4.3.0 stacked_firebase_auth: path: ../ dev_dependencies: - build_runner: ^2.4.5 + build_runner: ^2.7.1 flutter_test: sdk: flutter - flutter_lints: ^2.0.0 - mockito: ^5.4.1 - stacked_generator: ^1.3.3 + flutter_lints: ^6.0.0 + mockito: ^5.4.4 + stacked_generator: ^2.0.0 dependency_overrides: stacked_firebase_auth: diff --git a/example/test/helpers/test_helpers.dart b/example/test/helpers/test_helpers.dart index f8639eb..d12bcdb 100644 --- a/example/test/helpers/test_helpers.dart +++ b/example/test/helpers/test_helpers.dart @@ -1,6 +1,7 @@ import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:example/app/app.locator.dart'; +import 'package:stacked_firebase_auth/stacked_firebase_auth.dart'; import 'package:stacked_services/stacked_services.dart'; // @stacked-import @@ -10,15 +11,24 @@ import 'test_helpers.mocks.dart'; MockSpec(onMissingStub: OnMissingStub.returnDefault), MockSpec(onMissingStub: OnMissingStub.returnDefault), MockSpec(onMissingStub: OnMissingStub.returnDefault), + MockSpec(onMissingStub: OnMissingStub.returnDefault), // @stacked-mock-spec ]) void registerServices() { getAndRegisterNavigationService(); getAndRegisterBottomSheetService(); getAndRegisterDialogService(); + getAndRegisterFirebaseAuthenticationService(); // @stacked-mock-register } +MockFirebaseAuthenticationService getAndRegisterFirebaseAuthenticationService() { + _removeRegistrationIfExists(); + final service = MockFirebaseAuthenticationService(); + locator.registerSingleton(service); + return service; +} + MockNavigationService getAndRegisterNavigationService() { _removeRegistrationIfExists(); final service = MockNavigationService(); diff --git a/example/test/helpers/test_helpers.mocks.dart b/example/test/helpers/test_helpers.mocks.dart index 585049c..0b1af33 100644 --- a/example/test/helpers/test_helpers.mocks.dart +++ b/example/test/helpers/test_helpers.mocks.dart @@ -1,15 +1,18 @@ -// Mocks generated by Mockito 5.4.4 from annotations +// Mocks generated by Mockito 5.4.6 from annotations // in example/test/helpers/test_helpers.dart. // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i5; -import 'dart:ui' as _i6; +import 'dart:async' as _i7; +import 'dart:ui' as _i8; -import 'package:flutter/material.dart' as _i4; +import 'package:firebase_auth/firebase_auth.dart' as _i2; +import 'package:flutter/material.dart' as _i6; import 'package:mockito/mockito.dart' as _i1; -import 'package:mockito/src/dummies.dart' as _i3; -import 'package:stacked_services/stacked_services.dart' as _i2; +import 'package:mockito/src/dummies.dart' as _i5; +import 'package:stacked_firebase_auth/src/firebase_authentication_service.dart' + as _i3; +import 'package:stacked_services/stacked_services.dart' as _i4; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -19,23 +22,56 @@ import 'package:stacked_services/stacked_services.dart' as _i2; // ignore_for_file: deprecated_member_use_from_same_package // ignore_for_file: implementation_imports // ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: must_be_immutable // ignore_for_file: prefer_const_constructors // ignore_for_file: unnecessary_parenthesis // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class +class _FakeFirebaseAuth_0 extends _i1.SmartFake implements _i2.FirebaseAuth { + _FakeFirebaseAuth_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeFirebaseAuthenticationResult_1 extends _i1.SmartFake + implements _i3.FirebaseAuthenticationResult { + _FakeFirebaseAuthenticationResult_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeConfirmationResult_2 extends _i1.SmartFake + implements _i2.ConfirmationResult { + _FakeConfirmationResult_2( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + /// A class which mocks [NavigationService]. /// /// See the documentation for Mockito's code generation for more information. -class MockNavigationService extends _i1.Mock implements _i2.NavigationService { +class MockNavigationService extends _i1.Mock implements _i4.NavigationService { @override String get previousRoute => (super.noSuchMethod( Invocation.getter(#previousRoute), - returnValue: _i3.dummyValue( + returnValue: _i5.dummyValue( this, Invocation.getter(#previousRoute), ), - returnValueForMissingStub: _i3.dummyValue( + returnValueForMissingStub: _i5.dummyValue( this, Invocation.getter(#previousRoute), ), @@ -44,25 +80,25 @@ class MockNavigationService extends _i1.Mock implements _i2.NavigationService { @override String get currentRoute => (super.noSuchMethod( Invocation.getter(#currentRoute), - returnValue: _i3.dummyValue( + returnValue: _i5.dummyValue( this, Invocation.getter(#currentRoute), ), - returnValueForMissingStub: _i3.dummyValue( + returnValueForMissingStub: _i5.dummyValue( this, Invocation.getter(#currentRoute), ), ) as String); @override - _i4.GlobalKey<_i4.NavigatorState>? nestedNavigationKey(int? index) => + _i6.GlobalKey<_i6.NavigatorState>? nestedNavigationKey(int? index) => (super.noSuchMethod( Invocation.method( #nestedNavigationKey, [index], ), returnValueForMissingStub: null, - ) as _i4.GlobalKey<_i4.NavigatorState>?); + ) as _i6.GlobalKey<_i6.NavigatorState>?); @override void config({ @@ -71,7 +107,7 @@ class MockNavigationService extends _i1.Mock implements _i2.NavigationService { bool? defaultOpaqueRoute, Duration? defaultDurationTransition, bool? defaultGlobalState, - _i2.Transition? defaultTransitionStyle, + _i4.Transition? defaultTransitionStyle, String? defaultTransition, }) => super.noSuchMethod( @@ -92,18 +128,18 @@ class MockNavigationService extends _i1.Mock implements _i2.NavigationService { ); @override - _i5.Future? navigateWithTransition( - _i4.Widget? page, { + _i7.Future? navigateWithTransition( + _i6.Widget? page, { bool? opaque, - String? transition = r'', + String? transition = '', Duration? duration, bool? popGesture, int? id, - _i4.Curve? curve, + _i6.Curve? curve, bool? fullscreenDialog = false, bool? preventDuplicates = true, - _i2.Transition? transitionClass, - _i2.Transition? transitionStyle, + _i4.Transition? transitionClass, + _i4.Transition? transitionStyle, String? routeName, }) => (super.noSuchMethod( @@ -125,21 +161,21 @@ class MockNavigationService extends _i1.Mock implements _i2.NavigationService { }, ), returnValueForMissingStub: null, - ) as _i5.Future?); + ) as _i7.Future?); @override - _i5.Future? replaceWithTransition( - _i4.Widget? page, { + _i7.Future? replaceWithTransition( + _i6.Widget? page, { bool? opaque, - String? transition = r'', + String? transition = '', Duration? duration, bool? popGesture, int? id, - _i4.Curve? curve, + _i6.Curve? curve, bool? fullscreenDialog = false, bool? preventDuplicates = true, - _i2.Transition? transitionClass, - _i2.Transition? transitionStyle, + _i4.Transition? transitionClass, + _i4.Transition? transitionStyle, String? routeName, }) => (super.noSuchMethod( @@ -161,7 +197,7 @@ class MockNavigationService extends _i1.Mock implements _i2.NavigationService { }, ), returnValueForMissingStub: null, - ) as _i5.Future?); + ) as _i7.Future?); @override bool back({ @@ -183,7 +219,7 @@ class MockNavigationService extends _i1.Mock implements _i2.NavigationService { @override void popUntil( - _i4.RoutePredicate? predicate, { + _i6.RoutePredicate? predicate, { int? id, }) => super.noSuchMethod( @@ -205,13 +241,13 @@ class MockNavigationService extends _i1.Mock implements _i2.NavigationService { ); @override - _i5.Future? navigateTo( + _i7.Future? navigateTo( String? routeName, { dynamic arguments, int? id, bool? preventDuplicates = true, Map? parameters, - _i4.RouteTransitionsBuilder? transition, + _i6.RouteTransitionsBuilder? transition, }) => (super.noSuchMethod( Invocation.method( @@ -226,21 +262,21 @@ class MockNavigationService extends _i1.Mock implements _i2.NavigationService { }, ), returnValueForMissingStub: null, - ) as _i5.Future?); + ) as _i7.Future?); @override - _i5.Future? navigateToView( - _i4.Widget? view, { + _i7.Future? navigateToView( + _i6.Widget? view, { dynamic arguments, int? id, bool? opaque, - _i4.Curve? curve, + _i6.Curve? curve, Duration? duration, bool? fullscreenDialog = false, bool? popGesture, bool? preventDuplicates = true, - _i2.Transition? transition, - _i2.Transition? transitionStyle, + _i4.Transition? transition, + _i4.Transition? transitionStyle, }) => (super.noSuchMethod( Invocation.method( @@ -260,16 +296,16 @@ class MockNavigationService extends _i1.Mock implements _i2.NavigationService { }, ), returnValueForMissingStub: null, - ) as _i5.Future?); + ) as _i7.Future?); @override - _i5.Future? replaceWith( + _i7.Future? replaceWith( String? routeName, { dynamic arguments, int? id, bool? preventDuplicates = true, Map? parameters, - _i4.RouteTransitionsBuilder? transition, + _i6.RouteTransitionsBuilder? transition, }) => (super.noSuchMethod( Invocation.method( @@ -284,10 +320,10 @@ class MockNavigationService extends _i1.Mock implements _i2.NavigationService { }, ), returnValueForMissingStub: null, - ) as _i5.Future?); + ) as _i7.Future?); @override - _i5.Future? clearStackAndShow( + _i7.Future? clearStackAndShow( String? routeName, { dynamic arguments, int? id, @@ -304,11 +340,11 @@ class MockNavigationService extends _i1.Mock implements _i2.NavigationService { }, ), returnValueForMissingStub: null, - ) as _i5.Future?); + ) as _i7.Future?); @override - _i5.Future? clearStackAndShowView( - _i4.Widget? view, { + _i7.Future? clearStackAndShowView( + _i6.Widget? view, { dynamic arguments, int? id, }) => @@ -322,10 +358,10 @@ class MockNavigationService extends _i1.Mock implements _i2.NavigationService { }, ), returnValueForMissingStub: null, - ) as _i5.Future?); + ) as _i7.Future?); @override - _i5.Future? clearTillFirstAndShow( + _i7.Future? clearTillFirstAndShow( String? routeName, { dynamic arguments, int? id, @@ -344,11 +380,11 @@ class MockNavigationService extends _i1.Mock implements _i2.NavigationService { }, ), returnValueForMissingStub: null, - ) as _i5.Future?); + ) as _i7.Future?); @override - _i5.Future? clearTillFirstAndShowView( - _i4.Widget? view, { + _i7.Future? clearTillFirstAndShowView( + _i6.Widget? view, { dynamic arguments, int? id, }) => @@ -362,12 +398,12 @@ class MockNavigationService extends _i1.Mock implements _i2.NavigationService { }, ), returnValueForMissingStub: null, - ) as _i5.Future?); + ) as _i7.Future?); @override - _i5.Future? pushNamedAndRemoveUntil( + _i7.Future? pushNamedAndRemoveUntil( String? routeName, { - _i4.RoutePredicate? predicate, + _i6.RoutePredicate? predicate, dynamic arguments, int? id, }) => @@ -382,16 +418,16 @@ class MockNavigationService extends _i1.Mock implements _i2.NavigationService { }, ), returnValueForMissingStub: null, - ) as _i5.Future?); + ) as _i7.Future?); } /// A class which mocks [BottomSheetService]. /// /// See the documentation for Mockito's code generation for more information. class MockBottomSheetService extends _i1.Mock - implements _i2.BottomSheetService { + implements _i4.BottomSheetService { @override - void setCustomSheetBuilders(Map? builders) => + void setCustomSheetBuilders(Map? builders) => super.noSuchMethod( Invocation.method( #setCustomSheetBuilders, @@ -401,10 +437,10 @@ class MockBottomSheetService extends _i1.Mock ); @override - _i5.Future<_i2.SheetResponse?> showBottomSheet({ + _i7.Future<_i4.SheetResponse?> showBottomSheet({ required String? title, String? description, - String? confirmButtonTitle = r'Ok', + String? confirmButtonTitle = 'Ok', String? cancelButtonTitle, bool? enableDrag = true, bool? barrierDismissible = true, @@ -413,6 +449,7 @@ class MockBottomSheetService extends _i1.Mock Duration? enterBottomSheetDuration, bool? ignoreSafeArea, bool? useRootNavigator = false, + double? elevation = 1.0, }) => (super.noSuchMethod( Invocation.method( @@ -430,15 +467,16 @@ class MockBottomSheetService extends _i1.Mock #enterBottomSheetDuration: enterBottomSheetDuration, #ignoreSafeArea: ignoreSafeArea, #useRootNavigator: useRootNavigator, + #elevation: elevation, }, ), - returnValue: _i5.Future<_i2.SheetResponse?>.value(), + returnValue: _i7.Future<_i4.SheetResponse?>.value(), returnValueForMissingStub: - _i5.Future<_i2.SheetResponse?>.value(), - ) as _i5.Future<_i2.SheetResponse?>); + _i7.Future<_i4.SheetResponse?>.value(), + ) as _i7.Future<_i4.SheetResponse?>); @override - _i5.Future<_i2.SheetResponse?> showCustomSheet({ + _i7.Future<_i4.SheetResponse?> showCustomSheet({ dynamic variant, String? title, String? description, @@ -451,10 +489,11 @@ class MockBottomSheetService extends _i1.Mock bool? showIconInAdditionalButton = false, String? additionalButtonTitle, bool? takesInput = false, - _i6.Color? barrierColor = const _i6.Color(2315255808), + _i8.Color? barrierColor = const _i8.Color(2315255808), + double? elevation = 1.0, bool? barrierDismissible = true, bool? isScrollControlled = false, - String? barrierLabel = r'', + String? barrierLabel = '', dynamic customData, R? data, bool? enableDrag = true, @@ -481,6 +520,7 @@ class MockBottomSheetService extends _i1.Mock #additionalButtonTitle: additionalButtonTitle, #takesInput: takesInput, #barrierColor: barrierColor, + #elevation: elevation, #barrierDismissible: barrierDismissible, #isScrollControlled: isScrollControlled, #barrierLabel: barrierLabel, @@ -493,12 +533,12 @@ class MockBottomSheetService extends _i1.Mock #useRootNavigator: useRootNavigator, }, ), - returnValue: _i5.Future<_i2.SheetResponse?>.value(), - returnValueForMissingStub: _i5.Future<_i2.SheetResponse?>.value(), - ) as _i5.Future<_i2.SheetResponse?>); + returnValue: _i7.Future<_i4.SheetResponse?>.value(), + returnValueForMissingStub: _i7.Future<_i4.SheetResponse?>.value(), + ) as _i7.Future<_i4.SheetResponse?>); @override - void completeSheet(_i2.SheetResponse? response) => + void completeSheet(_i4.SheetResponse? response) => super.noSuchMethod( Invocation.method( #completeSheet, @@ -511,10 +551,10 @@ class MockBottomSheetService extends _i1.Mock /// A class which mocks [DialogService]. /// /// See the documentation for Mockito's code generation for more information. -class MockDialogService extends _i1.Mock implements _i2.DialogService { +class MockDialogService extends _i1.Mock implements _i4.DialogService { @override void registerCustomDialogBuilders( - Map? builders) => + Map? builders) => super.noSuchMethod( Invocation.method( #registerCustomDialogBuilders, @@ -526,10 +566,10 @@ class MockDialogService extends _i1.Mock implements _i2.DialogService { @override void registerCustomDialogBuilder({ required dynamic variant, - required _i4.Widget Function( - _i4.BuildContext, - _i2.DialogRequest, - dynamic Function(_i2.DialogResponse), + required _i6.Widget Function( + _i6.BuildContext, + _i4.DialogRequest, + dynamic Function(_i4.DialogResponse), )? builder, }) => super.noSuchMethod( @@ -545,15 +585,17 @@ class MockDialogService extends _i1.Mock implements _i2.DialogService { ); @override - _i5.Future<_i2.DialogResponse?> showDialog({ + _i7.Future<_i4.DialogResponse?> showDialog({ String? title, String? description, String? cancelTitle, - _i6.Color? cancelTitleColor, - String? buttonTitle = r'Ok', - _i6.Color? buttonTitleColor, + _i8.Color? cancelTitleColor, + String? buttonTitle = 'Ok', + _i8.Color? buttonTitleColor, bool? barrierDismissible = false, - _i2.DialogPlatform? dialogPlatform, + _i6.RouteSettings? routeSettings, + _i6.GlobalKey<_i6.NavigatorState>? navigatorKey, + _i4.DialogPlatform? dialogPlatform, }) => (super.noSuchMethod( Invocation.method( @@ -567,16 +609,18 @@ class MockDialogService extends _i1.Mock implements _i2.DialogService { #buttonTitle: buttonTitle, #buttonTitleColor: buttonTitleColor, #barrierDismissible: barrierDismissible, + #routeSettings: routeSettings, + #navigatorKey: navigatorKey, #dialogPlatform: dialogPlatform, }, ), - returnValue: _i5.Future<_i2.DialogResponse?>.value(), + returnValue: _i7.Future<_i4.DialogResponse?>.value(), returnValueForMissingStub: - _i5.Future<_i2.DialogResponse?>.value(), - ) as _i5.Future<_i2.DialogResponse?>); + _i7.Future<_i4.DialogResponse?>.value(), + ) as _i7.Future<_i4.DialogResponse?>); @override - _i5.Future<_i2.DialogResponse?> showCustomDialog({ + _i7.Future<_i4.DialogResponse?> showCustomDialog({ dynamic variant, String? title, String? description, @@ -589,10 +633,13 @@ class MockDialogService extends _i1.Mock implements _i2.DialogService { bool? showIconInAdditionalButton = false, String? additionalButtonTitle, bool? takesInput = false, - _i6.Color? barrierColor = const _i6.Color(2315255808), + _i8.Color? barrierColor = const _i8.Color(2315255808), bool? barrierDismissible = false, - String? barrierLabel = r'', + String? barrierLabel = '', bool? useSafeArea = true, + _i6.RouteSettings? routeSettings, + _i6.GlobalKey<_i6.NavigatorState>? navigatorKey, + _i6.RouteTransitionsBuilder? transitionBuilder, dynamic customData, R? data, }) => @@ -617,24 +664,28 @@ class MockDialogService extends _i1.Mock implements _i2.DialogService { #barrierDismissible: barrierDismissible, #barrierLabel: barrierLabel, #useSafeArea: useSafeArea, + #routeSettings: routeSettings, + #navigatorKey: navigatorKey, + #transitionBuilder: transitionBuilder, #customData: customData, #data: data, }, ), - returnValue: _i5.Future<_i2.DialogResponse?>.value(), - returnValueForMissingStub: _i5.Future<_i2.DialogResponse?>.value(), - ) as _i5.Future<_i2.DialogResponse?>); + returnValue: _i7.Future<_i4.DialogResponse?>.value(), + returnValueForMissingStub: _i7.Future<_i4.DialogResponse?>.value(), + ) as _i7.Future<_i4.DialogResponse?>); @override - _i5.Future<_i2.DialogResponse?> showConfirmationDialog({ + _i7.Future<_i4.DialogResponse?> showConfirmationDialog({ String? title, String? description, - String? cancelTitle = r'Cancel', - _i6.Color? cancelTitleColor, - String? confirmationTitle = r'Ok', - _i6.Color? confirmationTitleColor, + String? cancelTitle = 'Cancel', + _i8.Color? cancelTitleColor, + String? confirmationTitle = 'Ok', + _i8.Color? confirmationTitleColor, bool? barrierDismissible = false, - _i2.DialogPlatform? dialogPlatform, + _i6.RouteSettings? routeSettings, + _i4.DialogPlatform? dialogPlatform, }) => (super.noSuchMethod( Invocation.method( @@ -648,16 +699,17 @@ class MockDialogService extends _i1.Mock implements _i2.DialogService { #confirmationTitle: confirmationTitle, #confirmationTitleColor: confirmationTitleColor, #barrierDismissible: barrierDismissible, + #routeSettings: routeSettings, #dialogPlatform: dialogPlatform, }, ), - returnValue: _i5.Future<_i2.DialogResponse?>.value(), + returnValue: _i7.Future<_i4.DialogResponse?>.value(), returnValueForMissingStub: - _i5.Future<_i2.DialogResponse?>.value(), - ) as _i5.Future<_i2.DialogResponse?>); + _i7.Future<_i4.DialogResponse?>.value(), + ) as _i7.Future<_i4.DialogResponse?>); @override - void completeDialog(_i2.DialogResponse? response) => + void completeDialog(_i4.DialogResponse? response) => super.noSuchMethod( Invocation.method( #completeDialog, @@ -666,3 +718,543 @@ class MockDialogService extends _i1.Mock implements _i2.DialogService { returnValueForMissingStub: null, ); } + +/// A class which mocks [FirebaseAuthenticationService]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockFirebaseAuthenticationService extends _i1.Mock + implements _i3.FirebaseAuthenticationService { + @override + _i2.FirebaseAuth get firebaseAuth => (super.noSuchMethod( + Invocation.getter(#firebaseAuth), + returnValue: _FakeFirebaseAuth_0( + this, + Invocation.getter(#firebaseAuth), + ), + returnValueForMissingStub: _FakeFirebaseAuth_0( + this, + Invocation.getter(#firebaseAuth), + ), + ) as _i2.FirebaseAuth); + + @override + bool get hasUser => (super.noSuchMethod( + Invocation.getter(#hasUser), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + _i7.Stream<_i2.User?> get authStateChanges => (super.noSuchMethod( + Invocation.getter(#authStateChanges), + returnValue: _i7.Stream<_i2.User?>.empty(), + returnValueForMissingStub: _i7.Stream<_i2.User?>.empty(), + ) as _i7.Stream<_i2.User?>); + + @override + _i7.Future emailExists(String? email) => (super.noSuchMethod( + Invocation.method( + #emailExists, + [email], + ), + returnValue: _i7.Future.value(false), + returnValueForMissingStub: _i7.Future.value(false), + ) as _i7.Future); + + @override + _i7.Future<_i3.FirebaseAuthenticationResult> signInWithGoogle( + {String? webLoginHint}) => + (super.noSuchMethod( + Invocation.method( + #signInWithGoogle, + [], + {#webLoginHint: webLoginHint}, + ), + returnValue: _i7.Future<_i3.FirebaseAuthenticationResult>.value( + _FakeFirebaseAuthenticationResult_1( + this, + Invocation.method( + #signInWithGoogle, + [], + {#webLoginHint: webLoginHint}, + ), + )), + returnValueForMissingStub: + _i7.Future<_i3.FirebaseAuthenticationResult>.value( + _FakeFirebaseAuthenticationResult_1( + this, + Invocation.method( + #signInWithGoogle, + [], + {#webLoginHint: webLoginHint}, + ), + )), + ) as _i7.Future<_i3.FirebaseAuthenticationResult>); + + @override + _i7.Future<_i3.FirebaseAuthenticationResult> signInWithFacebook( + {String? webLoginHint}) => + (super.noSuchMethod( + Invocation.method( + #signInWithFacebook, + [], + {#webLoginHint: webLoginHint}, + ), + returnValue: _i7.Future<_i3.FirebaseAuthenticationResult>.value( + _FakeFirebaseAuthenticationResult_1( + this, + Invocation.method( + #signInWithFacebook, + [], + {#webLoginHint: webLoginHint}, + ), + )), + returnValueForMissingStub: + _i7.Future<_i3.FirebaseAuthenticationResult>.value( + _FakeFirebaseAuthenticationResult_1( + this, + Invocation.method( + #signInWithFacebook, + [], + {#webLoginHint: webLoginHint}, + ), + )), + ) as _i7.Future<_i3.FirebaseAuthenticationResult>); + + @override + _i7.Future isAppleSignInAvailable() => (super.noSuchMethod( + Invocation.method( + #isAppleSignInAvailable, + [], + ), + returnValue: _i7.Future.value(false), + returnValueForMissingStub: _i7.Future.value(false), + ) as _i7.Future); + + @override + _i7.Future<_i3.FirebaseAuthenticationResult> signInWithApple({ + required String? appleRedirectUri, + required String? appleClientId, + bool? askForFullName = true, + }) => + (super.noSuchMethod( + Invocation.method( + #signInWithApple, + [], + { + #appleRedirectUri: appleRedirectUri, + #appleClientId: appleClientId, + #askForFullName: askForFullName, + }, + ), + returnValue: _i7.Future<_i3.FirebaseAuthenticationResult>.value( + _FakeFirebaseAuthenticationResult_1( + this, + Invocation.method( + #signInWithApple, + [], + { + #appleRedirectUri: appleRedirectUri, + #appleClientId: appleClientId, + #askForFullName: askForFullName, + }, + ), + )), + returnValueForMissingStub: + _i7.Future<_i3.FirebaseAuthenticationResult>.value( + _FakeFirebaseAuthenticationResult_1( + this, + Invocation.method( + #signInWithApple, + [], + { + #appleRedirectUri: appleRedirectUri, + #appleClientId: appleClientId, + #askForFullName: askForFullName, + }, + ), + )), + ) as _i7.Future<_i3.FirebaseAuthenticationResult>); + + @override + _i7.Future<_i3.FirebaseAuthenticationResult> loginAnonymously() => + (super.noSuchMethod( + Invocation.method( + #loginAnonymously, + [], + ), + returnValue: _i7.Future<_i3.FirebaseAuthenticationResult>.value( + _FakeFirebaseAuthenticationResult_1( + this, + Invocation.method( + #loginAnonymously, + [], + ), + )), + returnValueForMissingStub: + _i7.Future<_i3.FirebaseAuthenticationResult>.value( + _FakeFirebaseAuthenticationResult_1( + this, + Invocation.method( + #loginAnonymously, + [], + ), + )), + ) as _i7.Future<_i3.FirebaseAuthenticationResult>); + + @override + _i7.Future<_i3.FirebaseAuthenticationResult> loginWithEmail({ + required String? email, + required String? password, + }) => + (super.noSuchMethod( + Invocation.method( + #loginWithEmail, + [], + { + #email: email, + #password: password, + }, + ), + returnValue: _i7.Future<_i3.FirebaseAuthenticationResult>.value( + _FakeFirebaseAuthenticationResult_1( + this, + Invocation.method( + #loginWithEmail, + [], + { + #email: email, + #password: password, + }, + ), + )), + returnValueForMissingStub: + _i7.Future<_i3.FirebaseAuthenticationResult>.value( + _FakeFirebaseAuthenticationResult_1( + this, + Invocation.method( + #loginWithEmail, + [], + { + #email: email, + #password: password, + }, + ), + )), + ) as _i7.Future<_i3.FirebaseAuthenticationResult>); + + @override + _i7.Future<_i3.FirebaseAuthenticationResult> createAccountWithEmail({ + required String? email, + required String? password, + }) => + (super.noSuchMethod( + Invocation.method( + #createAccountWithEmail, + [], + { + #email: email, + #password: password, + }, + ), + returnValue: _i7.Future<_i3.FirebaseAuthenticationResult>.value( + _FakeFirebaseAuthenticationResult_1( + this, + Invocation.method( + #createAccountWithEmail, + [], + { + #email: email, + #password: password, + }, + ), + )), + returnValueForMissingStub: + _i7.Future<_i3.FirebaseAuthenticationResult>.value( + _FakeFirebaseAuthenticationResult_1( + this, + Invocation.method( + #createAccountWithEmail, + [], + { + #email: email, + #password: password, + }, + ), + )), + ) as _i7.Future<_i3.FirebaseAuthenticationResult>); + + @override + _i7.Future<_i2.ConfirmationResult> signInWithPhoneNumber( + String? phoneNumber) => + (super.noSuchMethod( + Invocation.method( + #signInWithPhoneNumber, + [phoneNumber], + ), + returnValue: + _i7.Future<_i2.ConfirmationResult>.value(_FakeConfirmationResult_2( + this, + Invocation.method( + #signInWithPhoneNumber, + [phoneNumber], + ), + )), + returnValueForMissingStub: + _i7.Future<_i2.ConfirmationResult>.value(_FakeConfirmationResult_2( + this, + Invocation.method( + #signInWithPhoneNumber, + [phoneNumber], + ), + )), + ) as _i7.Future<_i2.ConfirmationResult>); + + @override + _i7.Future<_i3.FirebaseAuthenticationResult> verifyOtp( + _i2.ConfirmationResult? confirmationResult, + String? otp, + ) => + (super.noSuchMethod( + Invocation.method( + #verifyOtp, + [ + confirmationResult, + otp, + ], + ), + returnValue: _i7.Future<_i3.FirebaseAuthenticationResult>.value( + _FakeFirebaseAuthenticationResult_1( + this, + Invocation.method( + #verifyOtp, + [ + confirmationResult, + otp, + ], + ), + )), + returnValueForMissingStub: + _i7.Future<_i3.FirebaseAuthenticationResult>.value( + _FakeFirebaseAuthenticationResult_1( + this, + Invocation.method( + #verifyOtp, + [ + confirmationResult, + otp, + ], + ), + )), + ) as _i7.Future<_i3.FirebaseAuthenticationResult>); + + @override + _i7.Future requestVerificationCode({ + required String? phoneNumber, + void Function(_i3.FirebaseAuthenticationResult)? onVerificationCompleted, + void Function(_i2.FirebaseAuthException)? onVerificationFailed, + void Function(String)? onCodeSent, + void Function(String)? onCodeTimeout, + String? autoRetrievedSmsCodeForTesting, + Duration? timeout = const Duration(seconds: 30), + int? forceResendingToken, + }) => + (super.noSuchMethod( + Invocation.method( + #requestVerificationCode, + [], + { + #phoneNumber: phoneNumber, + #onVerificationCompleted: onVerificationCompleted, + #onVerificationFailed: onVerificationFailed, + #onCodeSent: onCodeSent, + #onCodeTimeout: onCodeTimeout, + #autoRetrievedSmsCodeForTesting: autoRetrievedSmsCodeForTesting, + #timeout: timeout, + #forceResendingToken: forceResendingToken, + }, + ), + returnValue: _i7.Future.value(), + returnValueForMissingStub: _i7.Future.value(), + ) as _i7.Future); + + @override + _i7.Future<_i3.FirebaseAuthenticationResult> authenticateWithOtp( + String? otp) => + (super.noSuchMethod( + Invocation.method( + #authenticateWithOtp, + [otp], + ), + returnValue: _i7.Future<_i3.FirebaseAuthenticationResult>.value( + _FakeFirebaseAuthenticationResult_1( + this, + Invocation.method( + #authenticateWithOtp, + [otp], + ), + )), + returnValueForMissingStub: + _i7.Future<_i3.FirebaseAuthenticationResult>.value( + _FakeFirebaseAuthenticationResult_1( + this, + Invocation.method( + #authenticateWithOtp, + [otp], + ), + )), + ) as _i7.Future<_i3.FirebaseAuthenticationResult>); + + @override + _i7.Future<_i3.FirebaseAuthenticationResult> validateOtpAndLinkPhoneNumber( + String? otp) => + (super.noSuchMethod( + Invocation.method( + #validateOtpAndLinkPhoneNumber, + [otp], + ), + returnValue: _i7.Future<_i3.FirebaseAuthenticationResult>.value( + _FakeFirebaseAuthenticationResult_1( + this, + Invocation.method( + #validateOtpAndLinkPhoneNumber, + [otp], + ), + )), + returnValueForMissingStub: + _i7.Future<_i3.FirebaseAuthenticationResult>.value( + _FakeFirebaseAuthenticationResult_1( + this, + Invocation.method( + #validateOtpAndLinkPhoneNumber, + [otp], + ), + )), + ) as _i7.Future<_i3.FirebaseAuthenticationResult>); + + @override + _i7.Future logout() => (super.noSuchMethod( + Invocation.method( + #logout, + [], + ), + returnValue: _i7.Future.value(), + returnValueForMissingStub: _i7.Future.value(), + ) as _i7.Future); + + @override + _i7.Future sendResetPasswordLink(String? email) => (super.noSuchMethod( + Invocation.method( + #sendResetPasswordLink, + [email], + ), + returnValue: _i7.Future.value(false), + returnValueForMissingStub: _i7.Future.value(false), + ) as _i7.Future); + + @override + _i7.Future validatePassword(String? password) => (super.noSuchMethod( + Invocation.method( + #validatePassword, + [password], + ), + returnValue: _i7.Future.value(), + returnValueForMissingStub: _i7.Future.value(), + ) as _i7.Future); + + @override + _i7.Future updatePassword(String? password) => (super.noSuchMethod( + Invocation.method( + #updatePassword, + [password], + ), + returnValue: _i7.Future.value(), + returnValueForMissingStub: _i7.Future.value(), + ) as _i7.Future); + + @override + _i7.Future updateEmail(String? email) => (super.noSuchMethod( + Invocation.method( + #updateEmail, + [email], + ), + returnValue: _i7.Future.value(), + returnValueForMissingStub: _i7.Future.value(), + ) as _i7.Future); + + @override + _i7.Future verifyBeforeUpdateEmail(String? email) => + (super.noSuchMethod( + Invocation.method( + #verifyBeforeUpdateEmail, + [email], + ), + returnValue: _i7.Future.value(), + returnValueForMissingStub: _i7.Future.value(), + ) as _i7.Future); + + @override + _i7.Future updateDisplayName(String? displayName) => + (super.noSuchMethod( + Invocation.method( + #updateDisplayName, + [displayName], + ), + returnValue: _i7.Future.value(), + returnValueForMissingStub: _i7.Future.value(), + ) as _i7.Future); + + @override + _i7.Future updatePhotoURL(String? photoUrl) => (super.noSuchMethod( + Invocation.method( + #updatePhotoURL, + [photoUrl], + ), + returnValue: _i7.Future.value(), + returnValueForMissingStub: _i7.Future.value(), + ) as _i7.Future); + + @override + String generateNonce([int? length = 32]) => (super.noSuchMethod( + Invocation.method( + #generateNonce, + [length], + ), + returnValue: _i5.dummyValue( + this, + Invocation.method( + #generateNonce, + [length], + ), + ), + returnValueForMissingStub: _i5.dummyValue( + this, + Invocation.method( + #generateNonce, + [length], + ), + ), + ) as String); + + @override + String sha256ofString(String? input) => (super.noSuchMethod( + Invocation.method( + #sha256ofString, + [input], + ), + returnValue: _i5.dummyValue( + this, + Invocation.method( + #sha256ofString, + [input], + ), + ), + returnValueForMissingStub: _i5.dummyValue( + this, + Invocation.method( + #sha256ofString, + [input], + ), + ), + ) as String); +} diff --git a/lib/src/firebase_authentication_service.dart b/lib/src/firebase_authentication_service.dart index d1b519c..1ea8652 100644 --- a/lib/src/firebase_authentication_service.dart +++ b/lib/src/firebase_authentication_service.dart @@ -17,7 +17,8 @@ class FirebaseAuthenticationService { final Logger? log; final firebaseAuth = FirebaseAuth.instance; - final GoogleSignIn _googleSignIn = GoogleSignIn(); + final GoogleSignIn _googleSignIn = GoogleSignIn.instance; + bool _googleSignInInitialized = false; FirebaseAuthenticationService({ @Deprecated( @@ -65,10 +66,11 @@ class FirebaseAuthenticationService { ) Future emailExists(String email) async { try { - final signInMethods = - await firebaseAuth.fetchSignInMethodsForEmail(email); - - return signInMethods.length > 0; + // fetchSignInMethodsForEmail was removed in Firebase Auth 6.0+ + // This method is deprecated and should not be used + // Return false as a safe default + log?.w('emailExists() is deprecated and no longer supported. Returning false.'); + return false; } on FirebaseAuthException catch (e) { return e.code.toLowerCase() == 'invalid-email'; } @@ -100,21 +102,42 @@ class FirebaseAuthenticationService { /// On native platforms, a 3rd party library, like GoogleSignIn, is /// required to trigger the authentication flow. else { - final GoogleSignInAccount? googleSignInAccount = - await _googleSignIn.signIn(); - if (googleSignInAccount == null) { - log?.i('Process is canceled by the user'); + // Initialize GoogleSignIn if not already initialized + if (!_googleSignInInitialized) { + await _googleSignIn.initialize(); + _googleSignInInitialized = true; + } + + try { + // Authenticate the user first + await _googleSignIn.authenticate(); + } catch (e) { + log?.i('Google Sign In canceled or failed: $e'); return FirebaseAuthenticationResult.error( errorMessage: 'Google Sign In has been canceled by the user', exceptionCode: 'canceled', ); } - final GoogleSignInAuthentication googleSignInAuthentication = - await googleSignInAccount.authentication; + // Get authorization tokens for the required scopes + final authorization = + await _googleSignIn.authorizationClient.authorizationForScopes(['email']); + + final accessToken = authorization?.accessToken; + + if (accessToken == null) { + return FirebaseAuthenticationResult.error( + errorMessage: 'Failed to obtain Google authentication tokens', + exceptionCode: 'token-error', + ); + } + + // Create credential with accessToken + // Note: In google_sign_in 7.x, idToken is not available through authorizationForScopes + // Firebase Auth should work with accessToken alone final AuthCredential credential = GoogleAuthProvider.credential( - accessToken: googleSignInAuthentication.accessToken, - idToken: googleSignInAuthentication.idToken, + accessToken: accessToken, + idToken: null, ); userCredential = await _signInWithCredential(credential); @@ -187,7 +210,7 @@ class FirebaseAuthenticationService { final OAuthCredential facebookAuthCredential = FacebookAuthProvider.credential( - facebookLoginResult.accessToken!.token); + facebookLoginResult.accessToken!.tokenString); userCredential = await _signInWithCredential(facebookAuthCredential); } @@ -628,7 +651,9 @@ class FirebaseAuthenticationService { 'updateEmail() has been deprecated. Please use verifyBeforeUpdateEmail() instead.', ) Future updateEmail(String email) async { - await firebaseAuth.currentUser?.updateEmail(email); + // updateEmail() was removed in Firebase Auth 6.0+ + // Use verifyBeforeUpdateEmail() instead + await verifyBeforeUpdateEmail(email); } /// Sends a verification email to a new email address. The user's email will be updated to the new one after being verified. diff --git a/pubspec.yaml b/pubspec.yaml index 28e5232..ed20e8e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -13,23 +13,21 @@ dependencies: sdk: flutter # Firebase - firebase_core: ^3.4.0 - firebase_auth: ^5.2.0 - firebase_auth_platform_interface: ^7.0.0 + firebase_core: ^4.3.0 + firebase_auth: ^6.1.3 + firebase_auth_platform_interface: ^8.1.5 # Firebase Authentications - google_sign_in: ^6.2.1 - sign_in_with_apple: ^6.1.1 - flutter_facebook_auth: ^6.2.0 + google_sign_in: ^7.2.0 + sign_in_with_apple: ^7.0.1 + flutter_facebook_auth: ^7.1.5 # logging - logger: ^2.3.0 + logger: ^2.6.2 - crypto: ^3.0.3 + crypto: ^3.0.7 dev_dependencies: - flutter_lints: ^4.0.0 + flutter_lints: ^6.0.0 flutter_test: sdk: flutter - -flutter: \ No newline at end of file