flutterfire
flutterfire copied to clipboard
🐛 [Authentication] FirebaseUser.isAnonymous returns inconsistent values after Unlinking only provider
Bug report
Describe the bug
I have an anonymous user where isAnonymous
returns true.
If I then upgrade that user to a real user by linking it with some credentials but then unlink that same sign in provider, isAnonymous returns inconsistent values depending on application state.
Steps to reproduce
Steps to reproduce the behavior: Create an anonymous user
FirebaseAuth.signInAnonymously();
Link some credentials
AuthCredential authCredential = EmailAuthProvider.credential(email: email, password: pw);
FirebaseAuth.currentUser.linkWithCredential(authCredential))
Then unlink the same provider
FirebaseAuth.currentUser.
.getIdTokenResult(true)
.then((idTokenResult) => FirebaseAuth.currentUser.unlink(idTokenResult.signInProvider))
.then((user) =>
log("Signed anonymous user back in : uid=${user.uid} anonymous=${user.isAnonymous}",
Here user.isAnonymous
prints out true.
However, if you do a hot restart of the application and then check the state of the user
FirebaseAuth.currentUser.isAnoymous
This return false.
So there seems to be a mismatch of the isAnonymous value after unlinking and then when you refresh state.
Expected behavior
isAnonymous should be consistent and return true after unlink operation completes
Flutter doctor
Run flutter doctor
and paste the output below:
Click To Expand
For some reason I have Android studio setup correctly but it doesnt detect it.[✓] Flutter (Channel stable, 1.22.6, on macOS 11.1 20C69 darwin-x64, locale en-AU)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[✓] Xcode - develop for iOS and macOS (Xcode 12.4)
[!] Android Studio (version 4.1)
✗ Flutter plugin not installed; this adds Flutter specific functionality.
✗ Dart plugin not installed; this adds Dart specific functionality.
[!] IntelliJ IDEA Community Edition (version 2020.3.2)
✗ Flutter plugin not installed; this adds Flutter specific functionality.
✗ Dart plugin not installed; this adds Dart specific functionality.
[!] VS Code (version 1.52.1)
✗ Flutter extension not installed; install from
https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
[✓] Connected device (1 available)
! Doctor found issues in 3 categories.
Flutter dependencies
Run flutter pub deps -- --style=compact
and paste the output below:
Click To Expand
Dart SDK 2.10.5
Flutter SDK 1.22.6
siia 1.0.0+1
dependencies:
- animated_bottom_navigation_bar 0.2.1 [flutter]
- animations 1.1.2 [flutter]
- cloud_firestore 0.16.0 [flutter meta quiver firebase_core firebase_core_platform_interface cloud_firestore_platform_interface cloud_firestore_web]
- crypto 2.1.5 [collection convert typed_data]
- cupertino_icons 0.1.3
- equatable 1.2.5 [collection meta]
- firebase_auth 0.20.0+1 [meta firebase_core firebase_core_platform_interface firebase_auth_platform_interface firebase_auth_web flutter]
- firebase_core 0.7.0 [firebase_core_platform_interface flutter quiver meta firebase_core_web]
- flutter 0.0.0 [characters collection meta typed_data vector_math sky_engine]
- flutter_keyboard_visibility 3.2.2 [flutter]
- flutter_localizations 0.0.0 [flutter intl characters collection meta path typed_data vector_math]
- flutter_modular 2.0.1 [flutter]
- flutter_redux 0.6.0 [meta redux flutter]
- flutter_rounded_progress_bar 0.1.2 [flutter]
- flutter_translate 1.6.0 [flutter flutter_device_locale]
- form_field_validator 1.0.1 [flutter intl]
- get_it 4.0.4 [async meta]
- http 0.12.2 [http_parser path pedantic]
- intl 0.16.1 [path]
- json_annotation 3.1.0
- line_awesome_icons 1.0.4+2 [flutter]
- localstorage 3.0.6+9 [flutter path_provider]
- modal_bottom_sheet 1.0.0+1 [flutter]
- optional 5.0.0 [collection]
- path 1.8.0-nullsafety.1
- path_provider 1.6.27 [flutter path_provider_platform_interface path_provider_macos path_provider_linux path_provider_windows]
- quiver 2.1.5 [matcher meta]
- random_string 2.1.0
- redux 4.0.0+3
- scroll_to_index 1.0.6 [flutter]
- simple_animations 2.2.3 [flutter sa_multi_tween sa_anicoto sa_stateless_animation sa_v1_migration]
- supercharged 1.10.0 [supercharged_dart flutter]
- syncfusion_flutter_charts 18.4.35 [flutter intl vector_math syncfusion_flutter_core]
- universal_platform 0.1.3
- web_socket_channel 1.1.0 [async crypto stream_channel]
dev dependencies:
- build_runner 1.10.3 [args async build build_config build_daemon build_resolvers build_runner_core code_builder collection crypto dart_style glob graphs http_multi_server io js logging meta mime path pedantic pool pub_semver pubspec_parse shelf shelf_web_socket stack_trace stream_transform timing watcher web_socket_channel yaml]
- flutter_test 0.0.0 [flutter test_api path fake_async clock stack_trace vector_math async boolean_selector characters charcode collection matcher meta source_span stream_channel string_scanner term_glyph typed_data]
- json_serializable 3.5.1 [analyzer build build_config json_annotation meta path source_gen]
- mockito 4.1.3 [analyzer build code_builder collection dart_style matcher meta source_gen test_api]
- test 1.16.0-nullsafety.5 [analyzer async boolean_selector coverage http http_multi_server io js node_preamble package_config path pedantic pool shelf shelf_packages_handler shelf_static shelf_web_socket source_span stack_trace stream_channel typed_data web_socket_channel webkit_inspection_protocol yaml test_api test_core]
dependency overrides:
- pedantic 1.10.0-nullsafety.1
transitive dependencies:
- _fe_analyzer_shared 11.0.0 [meta]
- analyzer 0.40.4 [_fe_analyzer_shared args charcode cli_util collection convert crypto glob meta package_config path pub_semver source_span watcher yaml]
- args 1.6.0
- async 2.5.0-nullsafety.1 [collection]
- boolean_selector 2.1.0-nullsafety.1 [source_span string_scanner]
- build 1.5.0 [analyzer async convert crypto logging meta path glob]
- build_config 0.4.2 [checked_yaml json_annotation meta path pubspec_parse yaml]
- build_daemon 2.1.4 [built_collection built_value http_multi_server logging pedantic path pool shelf shelf_web_socket stream_transform watcher web_socket_channel]
- build_resolvers 1.4.2 [analyzer build crypto graphs logging meta path package_config pool pub_semver]
- build_runner_core 6.0.3 [async build build_config build_resolvers collection convert crypto glob graphs json_annotation logging meta path package_config pedantic pool timing watcher yaml]
- built_collection 4.3.2 [collection quiver]
- built_value 7.1.0 [built_collection collection fixnum quiver]
- characters 1.1.0-nullsafety.3
- charcode 1.2.0-nullsafety.1
- checked_yaml 1.0.2 [json_annotation source_span yaml]
- cli_util 0.1.4 [path]
- clock 1.1.0-nullsafety.1
- cloud_firestore_platform_interface 3.0.1 [flutter meta collection firebase_core plugin_platform_interface]
- cloud_firestore_web 0.3.0+1 [flutter flutter_web_plugins http_parser meta firebase_core firebase_core_web cloud_firestore_platform_interface js]
- code_builder 3.5.0 [built_collection built_value collection matcher meta]
- collection 1.15.0-nullsafety.3
- convert 2.1.1 [charcode typed_data]
- coverage 0.14.1 [args logging package_config path source_maps stack_trace vm_service]
- dart_style 1.3.8 [analyzer args path source_span]
- fake_async 1.2.0-nullsafety.1 [clock collection]
- ffi 0.1.3
- file 5.2.1 [intl meta path]
- firebase_auth_platform_interface 3.0.1 [flutter meta firebase_core plugin_platform_interface]
- firebase_auth_web 0.3.2+6 [flutter flutter_web_plugins meta http_parser intl firebase_core firebase_core_web firebase_auth_platform_interface js]
- firebase_core_platform_interface 3.0.1 [flutter meta plugin_platform_interface quiver]
- firebase_core_web 0.2.1+3 [firebase_core_platform_interface flutter flutter_web_plugins meta js]
- fixnum 0.10.11
- flutter_device_locale 0.4.0 [flutter flutter_web_plugins plugin_platform_interface]
- flutter_web_plugins 0.0.0 [flutter characters collection meta typed_data vector_math]
- glob 1.2.0 [async collection node_io path pedantic string_scanner]
- graphs 0.2.0
- http_multi_server 2.2.0 [async]
- http_parser 3.1.4 [charcode collection source_span string_scanner typed_data]
- io 0.3.4 [charcode meta path string_scanner]
- js 0.6.3-nullsafety.1
- logging 0.11.4
- matcher 0.12.10-nullsafety.1 [stack_trace]
- meta 1.3.0-nullsafety.3
- mime 0.9.7
- node_interop 1.1.1 [js]
- node_io 1.1.1 [node_interop path]
- node_preamble 1.4.12
- package_config 1.9.3 [path charcode]
- path_provider_linux 0.0.1+2 [path xdg_directories path_provider_platform_interface flutter]
- path_provider_macos 0.0.4+4 [flutter]
- path_provider_platform_interface 1.0.3 [flutter meta platform plugin_platform_interface]
- path_provider_windows 0.0.4+1 [path_provider_platform_interface meta path flutter ffi win32]
- platform 2.2.1
- plugin_platform_interface 1.0.3 [meta]
- pool 1.5.0-nullsafety.2 [async stack_trace]
- process 3.0.13 [file intl meta path platform]
- pub_semver 1.4.4 [collection]
- pubspec_parse 0.1.5 [checked_yaml json_annotation pub_semver yaml]
- sa_anicoto 1.0.3 [flutter supercharged]
- sa_multi_tween 1.1.3 [flutter supercharged]
- sa_stateless_animation 1.0.3 [flutter supercharged sa_anicoto]
- sa_v1_migration 1.1.2 [flutter]
- shelf 0.7.9 [async collection http_parser path stack_trace stream_channel]
- shelf_packages_handler 2.0.0 [path shelf shelf_static]
- shelf_static 0.2.8 [convert http_parser mime path shelf]
- shelf_web_socket 0.2.3 [shelf web_socket_channel stream_channel]
- sky_engine 0.0.99
- source_gen 0.9.7+1 [analyzer async build dart_style glob meta path pedantic source_span]
- source_map_stack_trace 2.1.0-nullsafety.3 [path stack_trace source_maps]
- source_maps 0.10.10-nullsafety.2 [source_span]
- source_span 1.8.0-nullsafety.2 [charcode collection path term_glyph]
- stack_trace 1.10.0-nullsafety.1 [path]
- stream_channel 2.1.0-nullsafety.1 [async]
- stream_transform 1.2.0
- string_scanner 1.1.0-nullsafety.1 [charcode source_span]
- supercharged_dart 1.2.0
- syncfusion_flutter_core 18.4.35+1 [flutter]
- term_glyph 1.2.0-nullsafety.1
- test_api 0.2.19-nullsafety.2 [async boolean_selector collection meta path source_span stack_trace stream_channel string_scanner term_glyph matcher]
- test_core 0.3.12-nullsafety.5 [analyzer async args boolean_selector collection coverage glob io meta package_config path pedantic pool source_map_stack_trace source_maps source_span stack_trace stream_channel vm_service yaml matcher test_api]
- timing 0.1.1+2 [json_annotation]
- typed_data 1.3.0-nullsafety.3 [collection]
- vector_math 2.1.0-nullsafety.3
- vm_service 5.2.0 [meta]
- watcher 0.9.7+15 [async path pedantic]
- webkit_inspection_protocol 0.7.3 [logging]
- win32 1.7.3 [ffi]
- xdg_directories 0.1.2 [meta path process]
- yaml 2.2.1 [charcode collection string_scanner source_span]
Also, to prove there is a state problem here below are two log outputs obtained from subscribing to the user changes stream When I initially link the anonymous user to email/pw credentials, you can see that the state updates correctly, showing the new provider information and isAnonymous is false as it should be.
[log] User changed : user=User(displayName: TEACHER, email: [email protected], emailVerified: false, isAnonymous: false, metadata: UserMetadata(creationTime: 2021-02-02 10:10:32.352, lastSignInTime: 2021-02-02 10:10:32.352), phoneNumber: null, photoURL: null, providerData, [UserInfo(displayName: TEACHER, email: [email protected], phoneNumber: null, photoURL: null, providerId: password, uid: [email protected])], refreshToken: , tenantId: null, uid: 8MJtNBP8DAWGJpGGkVDCaPctKdF3)
Then, when I unlink the password provider, the stream again publishes an updates showing the new user with the provider removed and now isAnonymous is true.
[log] User changed : user=User(displayName: TEACHER, email: null, emailVerified: false, isAnonymous: true, metadata: UserMetadata(creationTime: 2021-02-02 10:10:32.352, lastSignInTime: 2021-02-02 10:10:32.352), phoneNumber: null, photoURL: null, providerData, [], refreshToken: , tenantId: null, uid: 8MJtNBP8DAWGJpGGkVDCaPctKdF3)
But this state does not persist across app restarts/hot restart. When you retrieve the user for the first time isAnonymous is set to false again.
I was able to reproduce this on the latest master 1.26.0-18.0.pre.125
with firebase_auth: ^0.20.0+1
.
flutter doctor -v
[√] Flutter (Channel master, 1.26.0-18.0.pre.125, on Microsoft Windows [Version 10.0.19041.746], locale et-EE)
• Flutter version 1.26.0-18.0.pre.125 at C:\Development\flutter_master
• Framework revision 11609d1114 (2 hours ago), 2021-02-02 00:22:14 -0800
• Engine revision bb2bbde4d0
• Dart version 2.12.0 (build 2.12.0-279.0.dev)
[√] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
• Android SDK at C:\Users\marku\AppData\Local\Android\sdk
• Platform android-30, build-tools 30.0.2
• Java binary at: C:\Users\marku\AppData\Local\JetBrains\Toolbox\apps\AndroidStudio\ch-0\201.7042882\jre\bin\java
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
• All Android licenses accepted.
[√] Chrome - develop for the web
• Chrome at C:\Program Files\Google\Chrome\Application\chrome.exe
[√] Visual Studio - develop for Windows (Visual Studio Community 2019 16.7.7)
• Visual Studio at C:\Program Files (x86)\Microsoft Visual Studio\2019\Community
• Visual Studio Community 2019 version 16.7.30621.155
• Windows 10 SDK version 10.0.18362.0
[√] Android Studio (version 4.1.0)
• Android Studio at C:\Users\marku\AppData\Local\JetBrains\Toolbox\apps\AndroidStudio\ch-0\201.7042882
• Flutter plugin can be installed from:
https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
[√] Connected device (4 available)
• SM G950F (mobile) • ce12171c51cc001c03 • android-arm64 • Android 9 (API 28)
• Windows (desktop) • windows • windows-x64 • Microsoft Windows [Version 10.0.19041.746]
• Chrome (web) • chrome • web-javascript • Google Chrome 88.0.4324.104
• Edge (web) • edge • web-javascript • Microsoft Edge 88.0.705.56
• No issues found!
This isn't just a debug hot reload/hot restart thing. After terminating and reopening a release build it does the same thing. Used the official example with https://github.com/FirebaseExtended/flutterfire/pull/4635 to observe the behavior.
Could I get some insight into the release schedules for issues like this? How so you guys prioritise these and determine if a fix it will be shipped in a future release? I am trying to understand how to handle this problem on our end since its important to determining if the user is valid but its far from ideal so would like to know if we can expect a fix at some point soon or if it will not be prioritised for a while
I am currently experiencing this issue using the JavaScript APIs and it is identical. I unlink the last credential for an Auth user object that was initially anonymous, and unfortunately isAnonymous = false any time I retrieve that object again. According to the docs, after unlinking the last credential, isAnonymous should be true again.
This also occurs when using signInAnonymously()
to handle signing out a user directly to an anonymous user.
Some details:
- Android 12 Emulator
- Flutter 3.3.0
- firebase_auth: 3.8.0
Doing this sequence of action in Firebase Auth:
await FirebaseAuth.instance.signOut();
print('Before ${FirebaseAuth.instance.currentUser?.uid}');
await FirebaseAuth.instance.signInAnonymously();
AuthCredential authCredential = EmailAuthProvider.credential(
email: '[email protected]',
password: 'password',
);
await FirebaseAuth.instance.currentUser!.linkWithCredential(authCredential);
print('After linking ${FirebaseAuth.instance.currentUser!.uid}');
await FirebaseAuth.instance.signOut();
await FirebaseAuth.instance.signInWithEmailAndPassword(
email: '[email protected]',
password: 'password',
);
print('After login email ${FirebaseAuth.instance.currentUser!.uid}');
print(
'After login email ${FirebaseAuth.instance.currentUser!.isAnonymous}',
);
final idTokenResult =
await FirebaseAuth.instance.currentUser!.getIdTokenResult(true);
await FirebaseAuth.instance.currentUser!
.unlink(idTokenResult.signInProvider!);
print('After unlinking ${FirebaseAuth.instance.currentUser!.uid}');
print('After unlinking ${FirebaseAuth.instance.currentUser!.isAnonymous}');
Gives me the expected results:
I/flutter ( 710): Before null
I/flutter ( 710): After linking Q5Kor5XrrhcvdflP2hx2QsoCuLx2
I/flutter ( 710): After login email Q5Kor5XrrhcvdflP2hx2QsoCuLx2
I/flutter ( 710): After login email false
I/flutter ( 710): After unlinking Q5Kor5XrrhcvdflP2hx2QsoCuLx2
I/flutter ( 710): After unlinking true
Can you provide any complete reproduction code so we can help?
Hey @muzzah. We need more information to resolve this issue but there hasn't been an update in 7 weekdays. I'm marking the issue as stale and if there are no new updates in the next 7 days I will close it automatically.
If you have more information that will help us get to the bottom of this, just add a comment!
Since there haven't been any recent updates here, I am going to close this issue.
@muzzah if you're still experiencing this problem and want to continue the discussion just leave a comment here and we are happy to re-open this.