I have two Firebase projects both of which use Firebase Authentication from Android and iOS. On one project, authentication works properly and as expected.
On the troublesome project, Firebase Authentication does not work for any pre-existing users that already appear in the Firebase console. For those users, FirebaseUI improperly shows a screen to create a new account, and then if you proceed with this, the UI shows "Email account registration unsuccessful" and the following errors appear in the Android logs. The fact that account creation is unsuccessful is not really surprising as the user already exists. The real problem is that Firebase Auth UI should not show the account creation screen for existing users. No errors show in the logs when the account creation screen is shown.
Alternatively, if you create a brand new account with a unique email, everything works as expected. But then if you go out and go back in with this account, I get the same error sequence described above.
The Android code is identical between these to projects -- the only thing that differs is the google-services.json linking it to one of the two Firebase accounts. On the two iOS apps, equivalent symptoms exist with the problematic Firebase account. I have tried deleting and re-adding the email provider, but that makes no difference.
What could possibly be wrong with the problematic Firebase account?
2023-11-13 09:48:46.407 14512-14512/net.llamadigital.safetyonsite2 W/EmailProviderResponseHa: No providers known for user (<redacted>[email protected]) this email address may be reserved.
2023-11-13 09:48:46.416 14512-14512/net.llamadigital.safetyonsite2 E/AuthUI: A sign-in error occurred.
com.firebase.ui.auth.FirebaseUiException: Unknown error
at com.firebase.ui.auth.viewmodel.email.EmailProviderResponseHandler$StartWelcomeBackFlow.onSuccess(EmailProviderResponseHandler.java:111)
at com.firebase.ui.auth.viewmodel.email.EmailProviderResponseHandler$StartWelcomeBackFlow.onSuccess(EmailProviderResponseHandler.java:98)
at com.google.android.gms.tasks.zzm.run(com.google.android.gms:play-services-tasks@@18.0.2:1)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:294)
at android.app.ActivityThread.main(ActivityThread.java:8171)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
Here's the code used to launch the Sign In.
// Choose authentication providers
List<AuthUI.IdpConfig> providers = Arrays.asList(
new AuthUI.IdpConfig.EmailBuilder().build());
// You must provide a custom layout XML resource and configure at least one
// provider button ID. It's important that that you set the button ID for every provider
// that you have enabled.
AuthMethodPickerLayout customLayout = new AuthMethodPickerLayout
.Builder(R.layout.layout_login)
.setEmailButtonId(R.id.emailButton)
.build();
// Create and launch sign-in intent
Intent signInIntent = AuthUI.getInstance()
.createSignInIntentBuilder()
.setAuthMethodPickerLayout(customLayout)
.setAvailableProviders(providers)
.setTheme(R.style.Theme_SOS)
.build();
signInLauncher.launch(signInIntent);
If you want to use Firebase Authentication with ONLY the email option, you must first enable Google Authentication in Firebase Console. This is true even if you have no intention of using Google Authentication.
If you fail to do this, then Firebase console will not set up the OAuth keys needed for email authentication to work and you will have the symptoms described in my question. You can tell if this is the problem from the Android google-services.json file because the "oauth_client" value will be an empty array [] or will have only a single entry with "client_type": 1. In my case a proper "oauth_client" value has multiple entries like this:
"oauth_client": [
{
"client_id": "<redacted>.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "your.app.package.name",
"certificate_hash": "<redacted>"
}
},
{
"client_id": "<redacted>.apps.googleusercontent.com",
"client_type": 3
}
],
You don't actually have to use this Google Authentication. It can be disabled in the app code as shown in the code snippet in my question, which only enables email authentication. But again, the Google Authentication option must be enabled in console before you download your .json or .plist
The reason I did not have this problem in my first Firebase account is because I did have Google Authentication enabled during development, so everything worked. Once I moved to the production Firebase account, I never set up Google Authentication because I don't want it enabled. I did not realize that having Google Authentication set up in the Firebase Console is an undocumented requirement for email auth to function.