🐛 [firebase_auth][iOS] INVALID_LOGIN_CREDENTIALS error message is not properly parsed
Is there an existing issue for this?
- [X] I have searched the existing issues and found no duplicates.
What plugin is this bug for?
Firebase UI Auth
What platform(s) does this bug affect?
iOS
List of dependencies used.
flutter pub deps -s list
Dart SDK 3.1.4
Flutter SDK 3.13.8
complete 0.1.0
dependencies:
- firebase_auth 4.13.0
- firebase_auth_platform_interface ^7.0.4
- firebase_auth_web ^5.8.7
- firebase_core ^2.22.0
- firebase_core_platform_interface ^5.0.0
- flutter any
- meta ^1.8.0
- firebase_core 2.22.0
- firebase_core_platform_interface ^5.0.0
- firebase_core_web ^2.8.1
- flutter any
- meta ^1.8.0
- firebase_ui_auth 1.10.0
- email_validator ^2.1.17
- firebase_auth ^4.11.1
- firebase_core ^2.19.0
- firebase_dynamic_links ^5.4.1
- firebase_ui_localizations ^1.8.0
- firebase_ui_oauth ^1.4.14
- firebase_ui_shared ^1.4.1
- flutter any
- flutter_localizations any
- firebase_ui_oauth_google 1.2.14
- firebase_auth ^4.11.1
- firebase_ui_oauth ^1.4.14
- flutter any
- google_sign_in ^6.1.0
- flutter 0.0.0
- characters 1.3.0
- collection 1.17.2
- material_color_utilities 0.5.0
- meta 1.9.1
- vector_math 2.1.4
- web 0.1.4-beta
- sky_engine any
- google_sign_in 6.1.6
- flutter any
- google_sign_in_android ^6.1.0
- google_sign_in_ios ^5.5.0
- google_sign_in_platform_interface ^2.4.0
- google_sign_in_web ^0.12.0
dev dependencies:
- flutter_test 0.0.0
- flutter any
- test_api 0.6.0
- matcher 0.12.16
- path 1.8.3
- fake_async 1.3.1
- clock 1.1.1
- stack_trace 1.11.0
- vector_math 2.1.4
- async 2.11.0
- boolean_selector 2.1.1
- characters 1.3.0
- collection 1.17.2
- material_color_utilities 0.5.0
- meta 1.9.1
- source_span 1.10.0
- stream_channel 2.1.1
- string_scanner 1.2.0
- term_glyph 1.2.1
- web 0.1.4-beta
- flutter_lints 3.0.1
- lints ^3.0.0
transitive dependencies:
- _fe_analyzer_shared 61.0.0
- meta ^1.0.2
- _flutterfire_internals 1.3.12
- collection ^1.0.0
- firebase_core ^2.22.0
- firebase_core_platform_interface ^5.0.0
- flutter any
- meta ^1.8.0
- analyzer 5.13.0
- _fe_analyzer_shared ^61.0.0
- collection ^1.17.0
- convert ^3.0.0
- crypto ^3.0.0
- glob ^2.0.0
- meta ^1.7.0
- package_config ^2.0.0
- path ^1.8.0
- pub_semver ^2.0.0
- source_span ^1.8.0
- watcher ^1.0.0
- yaml ^3.0.0
- args 2.4.2
- async 2.11.0
- collection ^1.15.0
- meta ^1.1.7
- boolean_selector 2.1.1
- source_span ^1.8.0
- string_scanner ^1.1.0
- characters 1.3.0
- clock 1.1.1
- collection 1.17.2
- convert 3.1.1
- typed_data ^1.3.0
- crypto 3.0.3
- typed_data ^1.3.0
- desktop_webview_auth 0.0.14
- crypto ^3.0.3
- flutter any
- http ^1.0.0
- flutter_web_plugins any
- plugin_platform_interface ^2.1.4
- email_validator 2.1.17
- fake_async 1.3.1
- clock ^1.1.0
- collection ^1.15.0
- file 7.0.0
- meta ^1.9.1
- path ^1.8.3
- firebase_auth_platform_interface 7.0.4
- _flutterfire_internals ^1.3.12
- collection ^1.16.0
- firebase_core ^2.22.0
- flutter any
- meta ^1.8.0
- plugin_platform_interface ^2.1.3
- firebase_auth_web 5.8.7
- firebase_auth_platform_interface ^7.0.4
- firebase_core ^2.22.0
- firebase_core_web ^2.8.1
- flutter any
- flutter_web_plugins any
- http_parser ^4.0.0
- js ^0.6.3
- meta ^1.8.0
- firebase_core_platform_interface 5.0.0
- collection ^1.0.0
- flutter any
- flutter_test any
- meta ^1.8.0
- plugin_platform_interface ^2.1.3
- firebase_core_web 2.8.1
- firebase_core_platform_interface ^5.0.0
- flutter any
- flutter_web_plugins any
- js ^0.6.3
- meta ^1.8.0
- firebase_dynamic_links 5.4.4
- firebase_core ^2.22.0
- firebase_core_platform_interface ^5.0.0
- firebase_dynamic_links_platform_interface ^0.2.6+12
- flutter any
- meta ^1.8.0
- plugin_platform_interface ^2.1.3
- firebase_dynamic_links_platform_interface 0.2.6+12
- _flutterfire_internals ^1.3.12
- firebase_core ^2.22.0
- flutter any
- meta ^1.8.0
- plugin_platform_interface ^2.1.3
- firebase_ui_localizations 1.8.0
- flutter any
- flutter_localizations any
- path ^1.8.2
- firebase_ui_oauth 1.4.14
- desktop_webview_auth ^0.0.13
- firebase_auth ^4.11.1
- firebase_ui_auth ^1.10.0
- firebase_ui_shared ^1.4.1
- flutter_svg ^2.0.7
- flutter any
- firebase_ui_shared 1.4.1
- flutter any
- flutter_localizations 0.0.0
- flutter any
- intl 0.18.1
- characters 1.3.0
- clock 1.1.1
- collection 1.17.2
- material_color_utilities 0.5.0
- meta 1.9.1
- path 1.8.3
- vector_math 2.1.4
- web 0.1.4-beta
- flutter_svg 2.0.9
- flutter any
- vector_graphics ^1.1.9+1
- vector_graphics_codec ^1.1.9+1
- vector_graphics_compiler ^1.1.9+1
- flutter_web_plugins 0.0.0
- flutter any
- characters 1.3.0
- collection 1.17.2
- material_color_utilities 0.5.0
- meta 1.9.1
- vector_math 2.1.4
- web 0.1.4-beta
- glob 2.1.2
- async ^2.5.0
- collection ^1.15.0
- file >=6.1.3 <8.0.0
- path ^1.8.0
- string_scanner ^1.1.0
- google_identity_services_web 0.2.2
- js ^0.6.4
- meta ^1.3.0
- google_sign_in_android 6.1.20
- flutter any
- google_sign_in_platform_interface ^2.2.0
- google_sign_in_ios 5.6.5
- flutter any
- google_sign_in_platform_interface ^2.2.0
- pigeon ^11.0.1
- google_sign_in_platform_interface 2.4.2
- flutter any
- plugin_platform_interface ^2.1.0
- quiver ^3.0.0
- google_sign_in_web 0.12.1
- flutter any
- flutter_web_plugins any
- google_identity_services_web ^0.2.2
- google_sign_in_platform_interface ^2.4.0
- http >=0.13.0 <2.0.0
- js ^0.6.3
- http 1.1.0
- async ^2.5.0
- http_parser ^4.0.0
- meta ^1.3.0
- http_parser 4.0.2
- collection ^1.15.0
- source_span ^1.8.0
- string_scanner ^1.1.0
- typed_data ^1.3.0
- intl 0.18.1
- clock ^1.1.0
- meta ^1.0.2
- path ^1.8.0
- js 0.6.7
- meta ^1.7.0
- lints 3.0.0
- matcher 0.12.16
- async ^2.10.0
- meta ^1.8.0
- stack_trace ^1.10.0
- term_glyph ^1.2.0
- test_api >=0.5.0 <0.7.0
- material_color_utilities 0.5.0
- collection ^1.15.0
- meta 1.9.1
- package_config 2.1.0
- path ^1.8.0
- path 1.8.3
- path_parsing 1.0.1
- vector_math ^2.1.0
- meta ^1.3.0
- petitparser 5.4.0
- meta ^1.9.0
- pigeon 11.0.1
- analyzer ^5.13.0
- args ^2.1.0
- collection ^1.15.0
- meta ^1.7.0
- path ^1.8.0
- yaml ^3.1.1
- plugin_platform_interface 2.1.6
- meta ^1.3.0
- pub_semver 2.1.4
- collection ^1.15.0
- meta ^1.3.0
- quiver 3.2.1
- matcher ^0.12.10
- sky_engine 0.0.99
- source_span 1.10.0
- collection ^1.15.0
- path ^1.8.0
- term_glyph ^1.2.0
- stack_trace 1.11.0
- path ^1.8.0
- stream_channel 2.1.1
- async ^2.5.0
- string_scanner 1.2.0
- source_span ^1.8.0
- term_glyph 1.2.1
- test_api 0.6.0
- async ^2.5.0
- boolean_selector ^2.1.0
- collection ^1.15.0
- meta ^1.3.0
- source_span ^1.8.0
- stack_trace ^1.10.0
- stream_channel ^2.1.0
- string_scanner ^1.1.0
- term_glyph ^1.2.0
- typed_data 1.3.2
- collection ^1.15.0
- vector_graphics 1.1.9+1
- flutter any
- vector_graphics_codec 1.1.9+1
- vector_graphics_codec 1.1.9+1
- vector_graphics_compiler 1.1.9+1
- args ^2.3.0
- meta ^1.7.0
- path_parsing ^1.0.1
- xml ^6.3.0
- vector_graphics_codec 1.1.9+1
- path ^1.8.0
- vector_math 2.1.4
- watcher 1.1.0
- async ^2.5.0
- path ^1.8.0
- web 0.1.4-beta
- xml 6.3.0
- collection ^1.17.0
- meta ^1.9.0
- petitparser ^5.4.0
- yaml 3.1.2
- collection ^1.15.0
- source_span ^1.8.0
- string_scanner ^1.1.0
Steps to reproduce
To reproduce just follow the steps in the FirebaseUI Auth codelab, specifically:
-
Codelab Step 2: Follow the instructions, make sure to create a new Firebase project. I used the free 'Spark` plan with default settings.
- NB This issue seems to be somehow related to the config of the Firebase project, so this is likely a critical step. See detaisl below.
-
Codelab Step 3: Get the starter code, or the 'complete' code from the Codelab GitHub Repository). I initially followed the entire lab but the Codelab implementation details don't affect this issue, so the easiest way is the shortcut and download the 'complete` project from GitHub
-
Note: I have had the same issue in all my
firebase_ui_authprojects (also see Issue firebase/FirebaseUI-Flutter#25), but the codelab project is the easiest way to reproduce and is what I used to investigate this issue (details below) -
Make sure to use
flutterfire configure, per the codelab, to generate thefirebase_options.dart -
In my case
flutterfire configuregenerated an error as follows:i Found 4 Firebase projects. Selecting project flutterfire-ui-codelab. FirebaseProjectNotFoundException: Firebase project id "flutterfire-ui-codelab" could not be found on this Firebase account.- Note that
flutterfire-ui-codelabis another (my initial) Firebase project (it's actuallyflutterfire-ui-codelab-e0f34, so there is possibily a seperate bug here withflutterfire config), and not the new, clean Firebase project I wanted to use for this test. To circumvent I explictly specified the Firebase project to be configured using:flutterfire configure -p flutterfire-ui-codelab2-260ce. This successfully generated myfirebase_options.dartfile.
- Note that
-
- Skip Codelab Steps 4-8: These are not needed if you've downloaded the 'complete' code from the Codelab GitHub Repository). Use the following steps instead
-
Step 4: In theory the codelab 'complete' code should now run... However in my case it generated the following error (which
flutter clean && flutter pub getdoes not resolve):Unhandled Exception: [core/duplicate-app] A Firebase App named "[DEFAULT]" already exists- This can be resolved in 2 ways (I've done both, with no impact to the issue here)
-
Step 4: Option a: The codelab 'complete' project has a
GoogleService-Info.plistin theios/Runnerfolder. Replacing this with theGoogleService-Info.plistfrom my own Firebase project is the simplest way to resolve the issue and will result in a working ios app displaying this issue -
Step 4: Option b: Delete the
iosfolder and its content and recreate theioscontent withflutter create . --platforms ios. This results in the same outcome as Step 4a
You should now have a working app which displays the issue documented here when run on an iOS simulator (I used both iPhone 14 and iPhone 14 Pro with the default (latest, I assume) iOS.
NOTE: There are 2 issues I identified with the codelab 'complete' code but which do not affect this issue here. For completeness these are:
- Issue 1: The images in
home.dartdon't display in the app because the image path is missingassets/before the image filename - Issue 2 (only arrises if Step 4b (ios re-create) is done): The
widget_test.dartfile (which is created when the ios app is re-created), does not recognise theMyApp()because the 'complete' code has a separateapp.dartfile for this class rather than it being part of the usualimport 'package:complete/main.dart';These issues are easily rectified, but as noted, don't effect the issue here.
Expected Behavior
The ios app should render reasonable user error messages in the app UI (via the SignInScreen widget) when the user enters invalid email and password credentials (either invalid / non-existent account, or wrong password).
Examples as follows:
NOTE: Having separate error messages for invalid / non-existent account and wrong password is, in my view, not a good security practice as it allows people to discover valid accounts and greatly simplifies hacking of passwords.
NOTE2: The error messages for web clients and android clients are different from the ios (expected behavior) messages above. The web client simply shows the text Error in red, while adnroid show different red text:
'An internal error has occurred. [ INVALID_LOGIN_CREDENTIALS ]'
In my view it would be a much better UX to show consistent error messages across all platforms. Also see Issue firebase/FirebaseUI-Flutter#25 where this is also discussed.
Actual Behavior
When the user enters invalid email and password credentials (either invalid / non-existent account, or wrong password) the following raw error message is rendered to the UI via the SignInScreen widget:
Full message when scrolling down:
I view this as an unacceptable and unusable User Experience, and it would prevent me from using the firebase_ui_auth package.
Additional Information
I believe this issue may be related to how the Firebase project is setup. Hence the emphasis in reproduction Step 2 above.
The reason for this is that there is another - not very good way, but an instructive way - to resolve the Unhandled Exception: [core/duplicate-app] A Firebase App named "[DEFAULT]" already exists issue I encountered at Step 4 above. I'll call this Step 4 - Option c and will describe the behavior and my associated hypothesis
-
Step 4 - Option c: Instead of replacing the
GoogleService-Info.plistfile, or recreating the ios build, it is possible to get the app working - with the expected error messages ! by adding aname:parameter to theFirebase.initializeAppinmain(). I discovered this while trying to debug the issue and from this StackOverflow article. Example as follows:
await Firebase.initializeApp(
name: 'test-app',
options: DefaultFirebaseOptions.currentPlatform,
);
- This results in a working app with the expected UI error messages (and was used to generate the screenshots in the Expected Behavior section
-
However this results in weird behavior where users that we previously registered in my Firebase project are no longer available, but new users can be registered and logged in. Furthermore these same new users can be accessed regardless of the
name:value used and don't appear anywhere in my Firebase project.
HYPOTHESIS:
Part 1: Using the combo of GoogleService-Info.plist and project.pbxproj from the original codelab complete folder seems to redirect my app to the codelab Firebase instance (PROJECT_ID flutterfire-ui-codelab referenced in GoogleService-Info.plist), which is why I can't see the users I've added there (like [email protected] and [email protected]) in my own Firebase project.
Part 2: Somehow the codelab Firebase instance (PROJECT_ID flutterfire-ui-codelab) is configured differently than mine and this causes the invalid credentials UI error messages to work correctly, while my basic, free and default Firebase config causes the bad UI error messages.
I hope all this helps track down this issue and helps to get it fixed.
Hi @Arik-AOS-dev, I suspect this is due to email enumeration protection being enabled on your project. Can you try disabling it to see if you do get the correct error messages? You can disable it by following https://cloud.google.com/identity-platform/docs/admin/email-enumeration-protection#disable
Hi @danagbemava-nc, many thanks for the response. I can confirm that indeed email enumeration protection is the source of this issue!
When I disable the email enumeration protection (per the instructions), the SignInScreen returns the expected error messages in the UI. FYI the setting which this came back for this in GCP console was simply:
"emailPrivacyConfig": {}
When I subsequently re-enabled the email enumeration protection in GCP console (and without any changes, or even reloads in my app) the UI error re-appeared. FYI the relevant returned setting in this case was:
"emailPrivacyConfig": {
"enableImprovedEmailPrivacy": true
}
While disabling email enumeration protection removes the issue, I hope we can agree it should not be a long-term workaround given a) it's now enabled by default (since Sept 15th, 2023) and b) Google recommends having it enabled. Coincidentally, I also mentioned this email enumeration issue in my NOTE: above in relation to the existing, expected error messages:
NOTE: Having separate error messages for invalid / non-existent account and wrong password is, in my view, not a good security practice as it allows people to discover valid accounts and greatly simplifies hacking of passwords.
It would be great if the resolution to this issue could also fix this and align the error messages for consistency across the platform. Thanks for the support !
Hi @Arik-AOS-dev, thanks for confirming.
So the error message is not from the firebase_ui_auth but from the underlying firebase_auth plugin.
Transferring this to the flutterfire repo.
Reproducible using the plugin auth example and a firebase project that has email enumeration protection enabled.
Triage report
To reproduce:
- Use the plugin example with a firebase project that has email enumeration protection enabled
- Test on iOS
- Attempt to sign in with either an invalid email and password or a valid email but invalid password
You will see the raw message instead of properly formatted message.
cc @russellwheatley
@Arik-AOS-dev Thanks for the report. I've checked and we actually don't get any nicely formatted messages from the iOS native SDK. Probably worth following up in the iOS repository.
@Lyokone, I'm experiencing this issue as well in my personal project, where I get firebase_auth/internal-error instead of the expected invalid-login-credentials when calling signInWithEmailAndPassword with invalid email or password. I would be happy to file an issue to get this resolved if you tell me which iOS repository you are referring to. I would also appreciate more details on what is needed from the iOS repo for the firebase_auth package to properly return invalid-login-credentials when entering an invalid email or password.
I've just tested this on in the auth example app across web, android and iOS. I got the same error:
[firebase_auth/invalid-credential] The supplied auth credential is incorrect, malformed or has expired.
Note; project needs email enumeration protection enabled to see it. If you see this issue on flutter-ui you should open the issue on that repo: https://github.com/firebase/FirebaseUI-Flutter
It is not an issue on FlutterFire.