From b6694cba1d707d70289013914a0ed4d635ea1d14 Mon Sep 17 00:00:00 2001 From: demolaf Date: Wed, 24 Jun 2026 16:02:31 +0100 Subject: [PATCH 1/3] feat(auth): add localized loading messages for various sign-in states --- .../com/firebase/ui/auth/FirebaseAuthUI.kt | 4 +- .../AnonymousAuthProvider+FirebaseAuthUI.kt | 3 +- .../EmailAuthProvider+FirebaseAuthUI.kt | 12 ++--- .../FacebookAuthProvider+FirebaseAuthUI.kt | 5 ++- .../GoogleAuthProvider+FirebaseAuthUI.kt | 3 +- .../OAuthProvider+FirebaseAuthUI.kt | 3 +- .../PhoneAuthProvider+FirebaseAuthUI.kt | 7 +-- .../string_provider/AuthUIStringProvider.kt | 45 +++++++++++++++++++ .../DefaultAuthUIStringProvider.kt | 38 +++++++++++++++- auth/src/main/res/values/strings.xml | 19 ++++++++ .../firebase/ui/auth/FirebaseAuthUITest.kt | 24 ++++++++++ ...AnonymousAuthProviderFirebaseAuthUITest.kt | 18 ++++++++ auth/src/test/res/values/strings.xml | 7 +++ 13 files changed, 170 insertions(+), 18 deletions(-) create mode 100644 auth/src/test/res/values/strings.xml diff --git a/auth/src/main/java/com/firebase/ui/auth/FirebaseAuthUI.kt b/auth/src/main/java/com/firebase/ui/auth/FirebaseAuthUI.kt index 45300cf23..5dba9843e 100644 --- a/auth/src/main/java/com/firebase/ui/auth/FirebaseAuthUI.kt +++ b/auth/src/main/java/com/firebase/ui/auth/FirebaseAuthUI.kt @@ -426,7 +426,7 @@ class FirebaseAuthUI private constructor( suspend fun signOut(context: Context) { try { // Update state to loading - updateAuthState(AuthState.Loading("Signing out...")) + updateAuthState(AuthState.Loading(context.getString(R.string.fui_loading_signing_out))) // Sign out from Firebase Auth auth.signOut() @@ -555,7 +555,7 @@ class FirebaseAuthUI private constructor( ) // Update state to loading - updateAuthState(AuthState.Loading("Deleting account...")) + updateAuthState(AuthState.Loading(context.getString(R.string.fui_loading_deleting_account))) // Delete the user account currentUser.delete().await() diff --git a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/AnonymousAuthProvider+FirebaseAuthUI.kt b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/AnonymousAuthProvider+FirebaseAuthUI.kt index baf9cef82..0106dc421 100644 --- a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/AnonymousAuthProvider+FirebaseAuthUI.kt +++ b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/AnonymousAuthProvider+FirebaseAuthUI.kt @@ -6,6 +6,7 @@ import androidx.compose.runtime.rememberCoroutineScope import com.firebase.ui.auth.AuthException import com.firebase.ui.auth.AuthState import com.firebase.ui.auth.FirebaseAuthUI +import com.firebase.ui.auth.R import kotlinx.coroutines.CancellationException import kotlinx.coroutines.launch import kotlinx.coroutines.tasks.await @@ -109,7 +110,7 @@ internal fun FirebaseAuthUI.rememberAnonymousSignInHandler(): () -> Unit { */ internal suspend fun FirebaseAuthUI.signInAnonymously() { try { - updateAuthState(AuthState.Loading("Signing in anonymously...")) + updateAuthState(AuthState.Loading(app.applicationContext.getString(R.string.fui_loading_signing_in_anonymously))) val result = auth.signInAnonymously().await() updateAuthStateWithResult(result, defaultIsNewUser = true) } catch (e: CancellationException) { diff --git a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/EmailAuthProvider+FirebaseAuthUI.kt b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/EmailAuthProvider+FirebaseAuthUI.kt index 515ad6afc..0e9bb1272 100644 --- a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/EmailAuthProvider+FirebaseAuthUI.kt +++ b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/EmailAuthProvider+FirebaseAuthUI.kt @@ -178,7 +178,7 @@ internal suspend fun FirebaseAuthUI.createOrLinkUserWithEmailAndPassword( } } - updateAuthState(AuthState.Loading("Creating user...")) + updateAuthState(AuthState.Loading(context.getString(R.string.fui_loading_creating_user))) val result = if (shouldLinkCredential) { auth.currentUser?.linkWithCredential(requireNotNull(pendingCredential))?.await() } else { @@ -344,7 +344,7 @@ internal suspend fun FirebaseAuthUI.signInWithEmailAndPassword( skipCredentialSave: Boolean = false, ): AuthResult? { try { - updateAuthState(AuthState.Loading("Signing in...")) + updateAuthState(AuthState.Loading(context.getString(R.string.fui_loading_signing_in))) // In reauth mode build a credential and go through signInAndLinkWithCredential so // signInOrReauth routes to FirebaseUser.reauthenticate() instead of signInWithCredential(). if (config.isReauthenticationMode) { @@ -645,7 +645,7 @@ internal suspend fun FirebaseAuthUI.signInAndLinkWithCredential( photoUrl: Uri? = null, ): AuthResult? { try { - updateAuthState(AuthState.Loading("Signing in user...")) + updateAuthState(AuthState.Loading(app.applicationContext.getString(R.string.fui_loading_linking_credential))) val result = if (canUpgradeAnonymous(config, auth) || canLinkCredential(config, auth)) { auth.currentUser?.linkWithCredential(credential)?.await() } else { @@ -830,7 +830,7 @@ internal suspend fun FirebaseAuthUI.sendSignInLinkToEmail( persistenceManager: PersistenceManager = EmailLinkPersistenceManager.default, ) { try { - updateAuthState(AuthState.Loading("Sending sign in email link...")) + updateAuthState(AuthState.Loading(context.getString(R.string.fui_loading_sending_email_link))) // Get anonymousUserId if can upgrade anonymously else default to empty string. // NOTE: check for empty string instead of null to validate anonymous user ID matches @@ -988,7 +988,7 @@ internal suspend fun FirebaseAuthUI.signInWithEmailLink( persistenceManager: PersistenceManager = EmailLinkPersistenceManager.default, ): AuthResult? { try { - updateAuthState(AuthState.Loading("Signing in with email link...")) + updateAuthState(AuthState.Loading(context.getString(R.string.fui_loading_signing_in_with_email_link))) // Validate link format if (!auth.isSignInWithEmailLink(emailLink)) { @@ -1259,7 +1259,7 @@ internal suspend fun FirebaseAuthUI.sendPasswordResetEmail( actionCodeSettings: ActionCodeSettings? = null, ) { try { - updateAuthState(AuthState.Loading("Sending password reset email...")) + updateAuthState(AuthState.Loading(app.applicationContext.getString(R.string.fui_loading_sending_password_reset))) auth.sendPasswordResetEmail(email, actionCodeSettings).await() updateAuthState(AuthState.PasswordResetLinkSent()) } catch (e: CancellationException) { diff --git a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/FacebookAuthProvider+FirebaseAuthUI.kt b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/FacebookAuthProvider+FirebaseAuthUI.kt index 674f02d33..f4b90fc16 100644 --- a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/FacebookAuthProvider+FirebaseAuthUI.kt +++ b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/FacebookAuthProvider+FirebaseAuthUI.kt @@ -30,6 +30,7 @@ import com.facebook.login.LoginResult import com.firebase.ui.auth.AuthException import com.firebase.ui.auth.AuthState import com.firebase.ui.auth.FirebaseAuthUI +import com.firebase.ui.auth.R import com.firebase.ui.auth.configuration.AuthUIConfiguration import com.firebase.ui.auth.util.EmailLinkPersistenceManager import com.firebase.ui.auth.util.SignInPreferenceManager @@ -114,7 +115,7 @@ internal fun FirebaseAuthUI.rememberSignInWithFacebookLauncher( return { updateAuthState( - AuthState.Loading("Signing in with facebook...") + AuthState.Loading(context.getString(R.string.fui_loading_signing_in_with_facebook)) ) try { (testLoginManagerProvider ?: loginManagerProvider).logOut() @@ -155,7 +156,7 @@ internal suspend fun FirebaseAuthUI.signInWithFacebook( ) { try { updateAuthState( - AuthState.Loading("Signing in with facebook...") + AuthState.Loading(context.getString(R.string.fui_loading_signing_in_with_facebook)) ) val profileData = provider.fetchFacebookProfile(accessToken) val credential = credentialProvider.getCredential(accessToken.token) diff --git a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/GoogleAuthProvider+FirebaseAuthUI.kt b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/GoogleAuthProvider+FirebaseAuthUI.kt index 496e1cd44..65110b9db 100644 --- a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/GoogleAuthProvider+FirebaseAuthUI.kt +++ b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/GoogleAuthProvider+FirebaseAuthUI.kt @@ -11,6 +11,7 @@ import androidx.credentials.exceptions.NoCredentialException import com.firebase.ui.auth.AuthException import com.firebase.ui.auth.AuthState import com.firebase.ui.auth.FirebaseAuthUI +import com.firebase.ui.auth.R import com.firebase.ui.auth.configuration.AuthUIConfiguration import com.firebase.ui.auth.util.EmailLinkPersistenceManager import com.firebase.ui.auth.util.SignInPreferenceManager @@ -119,7 +120,7 @@ internal suspend fun FirebaseAuthUI.signInWithGoogle( ) { var idTokenFromResult: String? = null try { - updateAuthState(AuthState.Loading("Signing in with google...")) + updateAuthState(AuthState.Loading(context.getString(R.string.fui_loading_signing_in_with_google))) // Request OAuth scopes if specified (before sign-in) if (provider.scopes.isNotEmpty()) { diff --git a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/OAuthProvider+FirebaseAuthUI.kt b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/OAuthProvider+FirebaseAuthUI.kt index ef974785f..571184d05 100644 --- a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/OAuthProvider+FirebaseAuthUI.kt +++ b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/OAuthProvider+FirebaseAuthUI.kt @@ -8,6 +8,7 @@ import androidx.compose.runtime.rememberCoroutineScope import com.firebase.ui.auth.AuthException import com.firebase.ui.auth.AuthState import com.firebase.ui.auth.FirebaseAuthUI +import com.firebase.ui.auth.R import com.firebase.ui.auth.configuration.AuthUIConfiguration import com.firebase.ui.auth.configuration.auth_provider.AuthProvider.Companion.canUpgradeAnonymous import com.firebase.ui.auth.util.SignInPreferenceManager @@ -129,7 +130,7 @@ internal suspend fun FirebaseAuthUI.signInWithProvider( provider: AuthProvider.OAuth, ) { try { - updateAuthState(AuthState.Loading("Signing in with ${provider.providerName}...")) + updateAuthState(AuthState.Loading(context.getString(R.string.fui_loading_signing_in_with_provider, provider.providerName))) // Build OAuth provider with scopes and custom parameters val oauthProvider = OAuthProvider diff --git a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/PhoneAuthProvider+FirebaseAuthUI.kt b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/PhoneAuthProvider+FirebaseAuthUI.kt index dd8662064..847bca672 100644 --- a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/PhoneAuthProvider+FirebaseAuthUI.kt +++ b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/PhoneAuthProvider+FirebaseAuthUI.kt @@ -5,6 +5,7 @@ import android.content.Context import com.firebase.ui.auth.AuthException import com.firebase.ui.auth.AuthState import com.firebase.ui.auth.FirebaseAuthUI +import com.firebase.ui.auth.R import com.firebase.ui.auth.configuration.AuthUIConfiguration import com.firebase.ui.auth.util.SignInPreferenceManager import com.google.firebase.auth.AuthResult @@ -111,7 +112,7 @@ internal suspend fun FirebaseAuthUI.verifyPhoneNumber( verifier: AuthProvider.Phone.Verifier = AuthProvider.Phone.DefaultVerifier(), ) { try { - updateAuthState(AuthState.Loading("Verifying phone number...")) + updateAuthState(AuthState.Loading((activity ?: app.applicationContext).getString(R.string.fui_loading_verifying_phone_number))) val result = provider.verifyPhoneNumberAwait( auth = auth, activity = activity, @@ -206,7 +207,7 @@ internal suspend fun FirebaseAuthUI.submitVerificationCode( credentialProvider: AuthProvider.Phone.CredentialProvider = AuthProvider.Phone.DefaultCredentialProvider(), ): AuthResult? { try { - updateAuthState(AuthState.Loading("Submitting verification code...")) + updateAuthState(AuthState.Loading(context.getString(R.string.fui_loading_submitting_verification_code))) val credential = credentialProvider.getCredential(verificationId, code) return signInWithPhoneAuthCredential( context = context, @@ -297,7 +298,7 @@ internal suspend fun FirebaseAuthUI.signInWithPhoneAuthCredential( credential: PhoneAuthCredential, ): AuthResult? { try { - updateAuthState(AuthState.Loading("Signing in with phone...")) + updateAuthState(AuthState.Loading(context.getString(R.string.fui_loading_signing_in_with_phone))) val result = signInAndLinkWithCredential( config = config, credential = credential, diff --git a/auth/src/main/java/com/firebase/ui/auth/configuration/string_provider/AuthUIStringProvider.kt b/auth/src/main/java/com/firebase/ui/auth/configuration/string_provider/AuthUIStringProvider.kt index bc7a8acdb..bc2ca3b43 100644 --- a/auth/src/main/java/com/firebase/ui/auth/configuration/string_provider/AuthUIStringProvider.kt +++ b/auth/src/main/java/com/firebase/ui/auth/configuration/string_provider/AuthUIStringProvider.kt @@ -49,6 +49,51 @@ interface AuthUIStringProvider { /** Loading text displayed during initialization or processing states */ val initializing: String + /** Progress dialog message shown while signing in anonymously */ + val loadingSigningInAnonymously: String + + /** Progress dialog message shown while signing in with Google */ + val loadingSigningInWithGoogle: String + + /** Progress dialog message shown while signing in with Facebook */ + val loadingSigningInWithFacebook: String + + /** Progress dialog message shown while signing in with a named OAuth provider. [providerName] is the display name of the provider. */ + fun loadingSigningInWithProvider(providerName: String): String + + /** Progress dialog message shown while verifying a phone number */ + val loadingVerifyingPhoneNumber: String + + /** Progress dialog message shown while submitting an SMS verification code */ + val loadingSubmittingVerificationCode: String + + /** Progress dialog message shown while completing phone number sign-in */ + val loadingSigningInWithPhone: String + + /** Progress dialog message shown while creating a new user account */ + val loadingCreatingUser: String + + /** Progress dialog message shown while signing in with email and password */ + val loadingSigningIn: String + + /** Progress dialog message shown while linking a credential to the current account */ + val loadingLinkingCredential: String + + /** Progress dialog message shown while sending the sign-in email link */ + val loadingSendingEmailLink: String + + /** Progress dialog message shown while completing an email link sign-in */ + val loadingSigningInWithEmailLink: String + + /** Progress dialog message shown while sending the password reset email */ + val loadingSendingPasswordResetEmail: String + + /** Progress dialog message shown while signing the user out */ + val loadingSigningOut: String + + /** Progress dialog message shown while deleting the user's account */ + val loadingDeletingAccount: String + /** Text for Google Provider */ val googleProvider: String diff --git a/auth/src/main/java/com/firebase/ui/auth/configuration/string_provider/DefaultAuthUIStringProvider.kt b/auth/src/main/java/com/firebase/ui/auth/configuration/string_provider/DefaultAuthUIStringProvider.kt index 3d2b9772d..cda581acb 100644 --- a/auth/src/main/java/com/firebase/ui/auth/configuration/string_provider/DefaultAuthUIStringProvider.kt +++ b/auth/src/main/java/com/firebase/ui/auth/configuration/string_provider/DefaultAuthUIStringProvider.kt @@ -38,7 +38,41 @@ class DefaultAuthUIStringProvider( * Common Strings */ override val initializing: String - get() = "Initializing" + get() = localizedContext.getString(R.string.fui_initializing) + + /** + * Loading State Strings + */ + override val loadingSigningInAnonymously: String + get() = localizedContext.getString(R.string.fui_loading_signing_in_anonymously) + override val loadingSigningInWithGoogle: String + get() = localizedContext.getString(R.string.fui_loading_signing_in_with_google) + override val loadingSigningInWithFacebook: String + get() = localizedContext.getString(R.string.fui_loading_signing_in_with_facebook) + override fun loadingSigningInWithProvider(providerName: String): String = + localizedContext.getString(R.string.fui_loading_signing_in_with_provider, providerName) + override val loadingVerifyingPhoneNumber: String + get() = localizedContext.getString(R.string.fui_loading_verifying_phone_number) + override val loadingSubmittingVerificationCode: String + get() = localizedContext.getString(R.string.fui_loading_submitting_verification_code) + override val loadingSigningInWithPhone: String + get() = localizedContext.getString(R.string.fui_loading_signing_in_with_phone) + override val loadingCreatingUser: String + get() = localizedContext.getString(R.string.fui_loading_creating_user) + override val loadingSigningIn: String + get() = localizedContext.getString(R.string.fui_loading_signing_in) + override val loadingLinkingCredential: String + get() = localizedContext.getString(R.string.fui_loading_linking_credential) + override val loadingSendingEmailLink: String + get() = localizedContext.getString(R.string.fui_loading_sending_email_link) + override val loadingSigningInWithEmailLink: String + get() = localizedContext.getString(R.string.fui_loading_signing_in_with_email_link) + override val loadingSendingPasswordResetEmail: String + get() = localizedContext.getString(R.string.fui_loading_sending_password_reset) + override val loadingSigningOut: String + get() = localizedContext.getString(R.string.fui_loading_signing_out) + override val loadingDeletingAccount: String + get() = localizedContext.getString(R.string.fui_loading_deleting_account) /** * Auth Provider strings @@ -278,7 +312,7 @@ class DefaultAuthUIStringProvider( * Multi-Factor Authentication Strings */ override val enterTOTPCode: String - get() = "Enter TOTP Code" + get() = localizedContext.getString(R.string.fui_enter_totp_code) /** * Provider Picker Strings diff --git a/auth/src/main/res/values/strings.xml b/auth/src/main/res/values/strings.xml index cc5cfa6b3..9c2ad8768 100644 --- a/auth/src/main/res/values/strings.xml +++ b/auth/src/main/res/values/strings.xml @@ -4,6 +4,24 @@ @string/app_name Loading… + Initializing + + + Signing in as guest… + Signing in with Google… + Signing in with Facebook… + Signing in with %1$s + Verifying phone number… + Submitting verification code… + Signing in with phone… + Creating account… + Signing in… + Signing in… + Sending sign-in link… + Signing in with email link… + Sending password reset email… + Signing out… + Deleting account… Sign in Continue By continuing, you are indicating that you accept our %1$s and %2$s. @@ -69,6 +87,7 @@ Authenticator app Unknown method Enrolled on %1$s + Enter TOTP code Scan the QR code or enter the secret key in your authenticator app Choose a verification method Add an extra layer of security diff --git a/auth/src/test/java/com/firebase/ui/auth/FirebaseAuthUITest.kt b/auth/src/test/java/com/firebase/ui/auth/FirebaseAuthUITest.kt index 7d5a75e3d..d0a15a85f 100644 --- a/auth/src/test/java/com/firebase/ui/auth/FirebaseAuthUITest.kt +++ b/auth/src/test/java/com/firebase/ui/auth/FirebaseAuthUITest.kt @@ -18,6 +18,7 @@ import android.content.Context import android.content.Intent import android.net.Uri import androidx.test.core.app.ApplicationProvider +import com.firebase.ui.auth.AuthState import com.firebase.ui.auth.configuration.auth_provider.AuthProvider import com.firebase.ui.auth.configuration.authUIConfiguration import com.google.android.gms.tasks.TaskCompletionSource @@ -30,6 +31,8 @@ import com.google.firebase.auth.FirebaseAuthRecentLoginRequiredException import com.google.firebase.auth.FirebaseUser import com.google.firebase.auth.UserInfo import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.launch import kotlinx.coroutines.test.runTest import org.junit.After import org.junit.Before @@ -362,6 +365,27 @@ class FirebaseAuthUITest { verify(mockAuth).signOut() } + @Test + fun `delete() emits Loading state with translated message`() = runTest { + val mockAuth = mock(FirebaseAuth::class.java) + val mockUser = mock(FirebaseUser::class.java) + `when`(mockAuth.currentUser).thenReturn(mockUser) + val taskCompletionSource = TaskCompletionSource() + `when`(mockUser.delete()).thenReturn(taskCompletionSource.task) + + val instance = FirebaseAuthUI.create(defaultApp, mockAuth) + val context = ApplicationProvider.getApplicationContext() + + // Queue delete first; first{} suspends and lets the scheduler run it + val job = launch { runCatching { instance.delete(context) } } + val loadingState = instance.authStateFlow().first { it is AuthState.Loading } + + assertThat((loadingState as AuthState.Loading).message) + .isEqualTo("test_loading_deleting_account") + + job.cancel() + } + @Test fun `signOut() handles Firebase exception and maps to AuthException`() = runTest { // Setup mock auth that throws exception diff --git a/auth/src/test/java/com/firebase/ui/auth/configuration/auth_provider/AnonymousAuthProviderFirebaseAuthUITest.kt b/auth/src/test/java/com/firebase/ui/auth/configuration/auth_provider/AnonymousAuthProviderFirebaseAuthUITest.kt index df4f6bcde..2a3b3c63c 100644 --- a/auth/src/test/java/com/firebase/ui/auth/configuration/auth_provider/AnonymousAuthProviderFirebaseAuthUITest.kt +++ b/auth/src/test/java/com/firebase/ui/auth/configuration/auth_provider/AnonymousAuthProviderFirebaseAuthUITest.kt @@ -33,6 +33,7 @@ import com.google.firebase.auth.FirebaseAuthUserCollisionException import com.google.firebase.auth.FirebaseUser import kotlinx.coroutines.CancellationException import kotlinx.coroutines.flow.first +import kotlinx.coroutines.launch import kotlinx.coroutines.test.runTest import org.junit.After import org.junit.Before @@ -115,6 +116,23 @@ class AnonymousAuthProviderFirebaseAuthUITest { assertThat(finalState).isEqualTo(AuthState.Success(result = mockAuthResult, user = mockUser, isNewUser = true)) } + @Test + fun `signInAnonymously - emits Loading state with translated message`() = runTest { + val taskCompletionSource = TaskCompletionSource() + `when`(mockFirebaseAuth.signInAnonymously()).thenReturn(taskCompletionSource.task) + + val instance = FirebaseAuthUI.create(firebaseApp, mockFirebaseAuth) + + // Queue signInAnonymously first; first{} suspends and lets the scheduler run it + val job = launch { runCatching { instance.signInAnonymously() } } + val loadingState = instance.authStateFlow().first { it is AuthState.Loading } + + assertThat((loadingState as AuthState.Loading).message) + .isEqualTo("test_loading_signing_in_anonymously") + + job.cancel() + } + @Test fun `signInAnonymously - handles network error`() = runTest { val networkException = FirebaseNetworkException("Network error") diff --git a/auth/src/test/res/values/strings.xml b/auth/src/test/res/values/strings.xml new file mode 100644 index 000000000..d3157138d --- /dev/null +++ b/auth/src/test/res/values/strings.xml @@ -0,0 +1,7 @@ + + + + test_loading_signing_in_anonymously + test_loading_deleting_account + From 0432a1fd0c2b6a51d20777a475cb60b9b238a208 Mon Sep 17 00:00:00 2001 From: demolaf Date: Wed, 24 Jun 2026 17:31:42 +0100 Subject: [PATCH 2/3] updates --- .../auth_provider/EmailAuthProvider+FirebaseAuthUI.kt | 10 +++++----- .../FacebookAuthProvider+FirebaseAuthUI.kt | 5 ++--- .../auth_provider/GoogleAuthProvider+FirebaseAuthUI.kt | 3 +-- .../auth_provider/OAuthProvider+FirebaseAuthUI.kt | 3 +-- .../auth_provider/PhoneAuthProvider+FirebaseAuthUI.kt | 4 ++-- 5 files changed, 11 insertions(+), 14 deletions(-) diff --git a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/EmailAuthProvider+FirebaseAuthUI.kt b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/EmailAuthProvider+FirebaseAuthUI.kt index 0e9bb1272..f802e51b9 100644 --- a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/EmailAuthProvider+FirebaseAuthUI.kt +++ b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/EmailAuthProvider+FirebaseAuthUI.kt @@ -178,7 +178,7 @@ internal suspend fun FirebaseAuthUI.createOrLinkUserWithEmailAndPassword( } } - updateAuthState(AuthState.Loading(context.getString(R.string.fui_loading_creating_user))) + updateAuthState(AuthState.Loading(config.stringProvider.loadingCreatingUser)) val result = if (shouldLinkCredential) { auth.currentUser?.linkWithCredential(requireNotNull(pendingCredential))?.await() } else { @@ -344,7 +344,7 @@ internal suspend fun FirebaseAuthUI.signInWithEmailAndPassword( skipCredentialSave: Boolean = false, ): AuthResult? { try { - updateAuthState(AuthState.Loading(context.getString(R.string.fui_loading_signing_in))) + updateAuthState(AuthState.Loading(config.stringProvider.loadingSigningIn)) // In reauth mode build a credential and go through signInAndLinkWithCredential so // signInOrReauth routes to FirebaseUser.reauthenticate() instead of signInWithCredential(). if (config.isReauthenticationMode) { @@ -645,7 +645,7 @@ internal suspend fun FirebaseAuthUI.signInAndLinkWithCredential( photoUrl: Uri? = null, ): AuthResult? { try { - updateAuthState(AuthState.Loading(app.applicationContext.getString(R.string.fui_loading_linking_credential))) + updateAuthState(AuthState.Loading(config.stringProvider.loadingLinkingCredential)) val result = if (canUpgradeAnonymous(config, auth) || canLinkCredential(config, auth)) { auth.currentUser?.linkWithCredential(credential)?.await() } else { @@ -830,7 +830,7 @@ internal suspend fun FirebaseAuthUI.sendSignInLinkToEmail( persistenceManager: PersistenceManager = EmailLinkPersistenceManager.default, ) { try { - updateAuthState(AuthState.Loading(context.getString(R.string.fui_loading_sending_email_link))) + updateAuthState(AuthState.Loading(config.stringProvider.loadingSendingEmailLink)) // Get anonymousUserId if can upgrade anonymously else default to empty string. // NOTE: check for empty string instead of null to validate anonymous user ID matches @@ -988,7 +988,7 @@ internal suspend fun FirebaseAuthUI.signInWithEmailLink( persistenceManager: PersistenceManager = EmailLinkPersistenceManager.default, ): AuthResult? { try { - updateAuthState(AuthState.Loading(context.getString(R.string.fui_loading_signing_in_with_email_link))) + updateAuthState(AuthState.Loading(config.stringProvider.loadingSigningInWithEmailLink)) // Validate link format if (!auth.isSignInWithEmailLink(emailLink)) { diff --git a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/FacebookAuthProvider+FirebaseAuthUI.kt b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/FacebookAuthProvider+FirebaseAuthUI.kt index f4b90fc16..d6a9622e7 100644 --- a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/FacebookAuthProvider+FirebaseAuthUI.kt +++ b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/FacebookAuthProvider+FirebaseAuthUI.kt @@ -30,7 +30,6 @@ import com.facebook.login.LoginResult import com.firebase.ui.auth.AuthException import com.firebase.ui.auth.AuthState import com.firebase.ui.auth.FirebaseAuthUI -import com.firebase.ui.auth.R import com.firebase.ui.auth.configuration.AuthUIConfiguration import com.firebase.ui.auth.util.EmailLinkPersistenceManager import com.firebase.ui.auth.util.SignInPreferenceManager @@ -115,7 +114,7 @@ internal fun FirebaseAuthUI.rememberSignInWithFacebookLauncher( return { updateAuthState( - AuthState.Loading(context.getString(R.string.fui_loading_signing_in_with_facebook)) + AuthState.Loading(config.stringProvider.loadingSigningInWithFacebook) ) try { (testLoginManagerProvider ?: loginManagerProvider).logOut() @@ -156,7 +155,7 @@ internal suspend fun FirebaseAuthUI.signInWithFacebook( ) { try { updateAuthState( - AuthState.Loading(context.getString(R.string.fui_loading_signing_in_with_facebook)) + AuthState.Loading(config.stringProvider.loadingSigningInWithFacebook) ) val profileData = provider.fetchFacebookProfile(accessToken) val credential = credentialProvider.getCredential(accessToken.token) diff --git a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/GoogleAuthProvider+FirebaseAuthUI.kt b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/GoogleAuthProvider+FirebaseAuthUI.kt index 65110b9db..89837df3e 100644 --- a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/GoogleAuthProvider+FirebaseAuthUI.kt +++ b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/GoogleAuthProvider+FirebaseAuthUI.kt @@ -11,7 +11,6 @@ import androidx.credentials.exceptions.NoCredentialException import com.firebase.ui.auth.AuthException import com.firebase.ui.auth.AuthState import com.firebase.ui.auth.FirebaseAuthUI -import com.firebase.ui.auth.R import com.firebase.ui.auth.configuration.AuthUIConfiguration import com.firebase.ui.auth.util.EmailLinkPersistenceManager import com.firebase.ui.auth.util.SignInPreferenceManager @@ -120,7 +119,7 @@ internal suspend fun FirebaseAuthUI.signInWithGoogle( ) { var idTokenFromResult: String? = null try { - updateAuthState(AuthState.Loading(context.getString(R.string.fui_loading_signing_in_with_google))) + updateAuthState(AuthState.Loading(config.stringProvider.loadingSigningInWithGoogle)) // Request OAuth scopes if specified (before sign-in) if (provider.scopes.isNotEmpty()) { diff --git a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/OAuthProvider+FirebaseAuthUI.kt b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/OAuthProvider+FirebaseAuthUI.kt index 571184d05..add6bb235 100644 --- a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/OAuthProvider+FirebaseAuthUI.kt +++ b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/OAuthProvider+FirebaseAuthUI.kt @@ -8,7 +8,6 @@ import androidx.compose.runtime.rememberCoroutineScope import com.firebase.ui.auth.AuthException import com.firebase.ui.auth.AuthState import com.firebase.ui.auth.FirebaseAuthUI -import com.firebase.ui.auth.R import com.firebase.ui.auth.configuration.AuthUIConfiguration import com.firebase.ui.auth.configuration.auth_provider.AuthProvider.Companion.canUpgradeAnonymous import com.firebase.ui.auth.util.SignInPreferenceManager @@ -130,7 +129,7 @@ internal suspend fun FirebaseAuthUI.signInWithProvider( provider: AuthProvider.OAuth, ) { try { - updateAuthState(AuthState.Loading(context.getString(R.string.fui_loading_signing_in_with_provider, provider.providerName))) + updateAuthState(AuthState.Loading(config.stringProvider.loadingSigningInWithProvider(provider.providerName))) // Build OAuth provider with scopes and custom parameters val oauthProvider = OAuthProvider diff --git a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/PhoneAuthProvider+FirebaseAuthUI.kt b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/PhoneAuthProvider+FirebaseAuthUI.kt index 847bca672..1a9bea124 100644 --- a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/PhoneAuthProvider+FirebaseAuthUI.kt +++ b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/PhoneAuthProvider+FirebaseAuthUI.kt @@ -207,7 +207,7 @@ internal suspend fun FirebaseAuthUI.submitVerificationCode( credentialProvider: AuthProvider.Phone.CredentialProvider = AuthProvider.Phone.DefaultCredentialProvider(), ): AuthResult? { try { - updateAuthState(AuthState.Loading(context.getString(R.string.fui_loading_submitting_verification_code))) + updateAuthState(AuthState.Loading(config.stringProvider.loadingSubmittingVerificationCode)) val credential = credentialProvider.getCredential(verificationId, code) return signInWithPhoneAuthCredential( context = context, @@ -298,7 +298,7 @@ internal suspend fun FirebaseAuthUI.signInWithPhoneAuthCredential( credential: PhoneAuthCredential, ): AuthResult? { try { - updateAuthState(AuthState.Loading(context.getString(R.string.fui_loading_signing_in_with_phone))) + updateAuthState(AuthState.Loading(config.stringProvider.loadingSigningInWithPhone)) val result = signInAndLinkWithCredential( config = config, credential = credential, From 54110a065b74e9a553559d521705c6e51e845077 Mon Sep 17 00:00:00 2001 From: demolaf Date: Thu, 25 Jun 2026 13:38:15 +0100 Subject: [PATCH 3/3] feat(auth): update sign-in methods to use AuthUIConfiguration for localized messages --- .../android/demo/HighLevelApiDemoActivity.kt | 26 ++++++++++++++++--- .../AnonymousAuthProvider+FirebaseAuthUI.kt | 10 +++---- .../EmailAuthProvider+FirebaseAuthUI.kt | 3 ++- .../PhoneAuthProvider+FirebaseAuthUI.kt | 4 +-- .../ui/auth/ui/screens/FirebaseAuthScreen.kt | 2 +- .../auth/ui/screens/email/EmailAuthScreen.kt | 1 + .../auth/ui/screens/phone/PhoneAuthScreen.kt | 2 ++ ...AnonymousAuthProviderFirebaseAuthUITest.kt | 20 ++++++++++---- .../EmailAuthProviderFirebaseAuthUITest.kt | 19 ++++++++++---- .../PhoneAuthProviderFirebaseAuthUITest.kt | 13 ++++++++++ 10 files changed, 78 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/com/firebaseui/android/demo/HighLevelApiDemoActivity.kt b/app/src/main/java/com/firebaseui/android/demo/HighLevelApiDemoActivity.kt index 145be42eb..8aabec3b0 100644 --- a/app/src/main/java/com/firebaseui/android/demo/HighLevelApiDemoActivity.kt +++ b/app/src/main/java/com/firebaseui/android/demo/HighLevelApiDemoActivity.kt @@ -50,6 +50,9 @@ import com.firebase.ui.auth.configuration.AuthUITransitions import com.firebase.ui.auth.configuration.PasswordRule import com.firebase.ui.auth.configuration.authUIConfiguration import com.firebase.ui.auth.configuration.auth_provider.AuthProvider +import com.firebase.ui.auth.configuration.string_provider.AuthUIStringProvider +import com.firebase.ui.auth.configuration.string_provider.AuthUIStringProviderSample.CustomAuthUIStringProvider +import com.firebase.ui.auth.configuration.string_provider.DefaultAuthUIStringProvider import com.firebase.ui.auth.configuration.theme.AuthUIAsset import com.firebase.ui.auth.configuration.theme.AuthUITheme import com.firebase.ui.auth.ui.screens.AuthSuccessUiContext @@ -71,6 +74,17 @@ class HighLevelApiDemoActivity : ComponentActivity() { providerButtonShape = ShapeDefaults.ExtraLarge ) + class CustomAuthUIStringProvider( + private val defaultProvider: AuthUIStringProvider + ) : AuthUIStringProvider by defaultProvider { + + override val loadingSigningInAnonymously: String + get() = "Overriding signing in anonymously loading message..." + } + + val customStringProvider = + CustomAuthUIStringProvider(DefaultAuthUIStringProvider(applicationContext)) + val configuration = authUIConfiguration { context = applicationContext theme = customTheme @@ -79,6 +93,7 @@ class HighLevelApiDemoActivity : ComponentActivity() { privacyPolicyUrl = "https://policies.google.com/privacy" isAnonymousUpgradeEnabled = false isMfaEnabled = false + stringProvider = customStringProvider transitions = AuthUITransitions( enterTransition = { slideInHorizontally { it } }, exitTransition = { slideOutHorizontally { -it } }, @@ -197,7 +212,10 @@ class HighLevelApiDemoActivity : ComponentActivity() { authUI = authUI, emailLink = emailLink, onSignInSuccess = { result -> - Log.d("HighLevelApiDemoActivity", "Authentication success: ${result.user?.uid}") + Log.d( + "HighLevelApiDemoActivity", + "Authentication success: ${result.user?.uid}" + ) }, onSignInFailure = { exception: AuthException -> Log.e("HighLevelApiDemoActivity", "Authentication failed", exception) @@ -327,7 +345,8 @@ private fun AppAuthenticatedContent( } is AuthState.RequiresEmailVerification -> { - val email = uiContext.authUI.getCurrentUser().getDisplayEmail(stringProvider.emailProvider) + val email = + uiContext.authUI.getCurrentUser().getDisplayEmail(stringProvider.emailProvider) Column( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, @@ -489,7 +508,8 @@ private fun ChangePasswordDialog( var updateError by remember { mutableStateOf(null) } val emailProvider = remember(configuration) { - configuration.providers.filterIsInstance().firstOrNull() + configuration.providers.filterIsInstance() + .firstOrNull() } val passwordValidator = remember(emailProvider, stringProvider) { com.firebase.ui.auth.configuration.validators.PasswordValidator( diff --git a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/AnonymousAuthProvider+FirebaseAuthUI.kt b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/AnonymousAuthProvider+FirebaseAuthUI.kt index 0106dc421..65ea606dd 100644 --- a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/AnonymousAuthProvider+FirebaseAuthUI.kt +++ b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/AnonymousAuthProvider+FirebaseAuthUI.kt @@ -6,7 +6,7 @@ import androidx.compose.runtime.rememberCoroutineScope import com.firebase.ui.auth.AuthException import com.firebase.ui.auth.AuthState import com.firebase.ui.auth.FirebaseAuthUI -import com.firebase.ui.auth.R +import com.firebase.ui.auth.configuration.AuthUIConfiguration import kotlinx.coroutines.CancellationException import kotlinx.coroutines.launch import kotlinx.coroutines.tasks.await @@ -20,14 +20,14 @@ import kotlinx.coroutines.tasks.await * @see createOrLinkUserWithEmailAndPassword for upgrading anonymous accounts */ @Composable -internal fun FirebaseAuthUI.rememberAnonymousSignInHandler(): () -> Unit { +internal fun FirebaseAuthUI.rememberAnonymousSignInHandler(config: AuthUIConfiguration): () -> Unit { val context = androidx.compose.ui.platform.LocalContext.current val coroutineScope = rememberCoroutineScope() return remember(this) { { coroutineScope.launch { try { - signInAnonymously() + signInAnonymously(config) } catch (e: AuthException) { // Already an AuthException, don't re-wrap it updateAuthState(AuthState.Error(e)) @@ -108,9 +108,9 @@ internal fun FirebaseAuthUI.rememberAnonymousSignInHandler(): () -> Unit { * @see createOrLinkUserWithEmailAndPassword for email/password upgrade * @see signInWithPhoneAuthCredential for phone authentication upgrade */ -internal suspend fun FirebaseAuthUI.signInAnonymously() { +internal suspend fun FirebaseAuthUI.signInAnonymously(config: AuthUIConfiguration) { try { - updateAuthState(AuthState.Loading(app.applicationContext.getString(R.string.fui_loading_signing_in_anonymously))) + updateAuthState(AuthState.Loading(config.stringProvider.loadingSigningInAnonymously)) val result = auth.signInAnonymously().await() updateAuthStateWithResult(result, defaultIsNewUser = true) } catch (e: CancellationException) { diff --git a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/EmailAuthProvider+FirebaseAuthUI.kt b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/EmailAuthProvider+FirebaseAuthUI.kt index f802e51b9..1e480eda9 100644 --- a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/EmailAuthProvider+FirebaseAuthUI.kt +++ b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/EmailAuthProvider+FirebaseAuthUI.kt @@ -1256,10 +1256,11 @@ private suspend fun FirebaseAuthUI.handleEmailLinkCredentialLinkingFlow( */ internal suspend fun FirebaseAuthUI.sendPasswordResetEmail( email: String, + config: AuthUIConfiguration, actionCodeSettings: ActionCodeSettings? = null, ) { try { - updateAuthState(AuthState.Loading(app.applicationContext.getString(R.string.fui_loading_sending_password_reset))) + updateAuthState(AuthState.Loading(config.stringProvider.loadingSendingPasswordResetEmail)) auth.sendPasswordResetEmail(email, actionCodeSettings).await() updateAuthState(AuthState.PasswordResetLinkSent()) } catch (e: CancellationException) { diff --git a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/PhoneAuthProvider+FirebaseAuthUI.kt b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/PhoneAuthProvider+FirebaseAuthUI.kt index 1a9bea124..24487dd58 100644 --- a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/PhoneAuthProvider+FirebaseAuthUI.kt +++ b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/PhoneAuthProvider+FirebaseAuthUI.kt @@ -5,7 +5,6 @@ import android.content.Context import com.firebase.ui.auth.AuthException import com.firebase.ui.auth.AuthState import com.firebase.ui.auth.FirebaseAuthUI -import com.firebase.ui.auth.R import com.firebase.ui.auth.configuration.AuthUIConfiguration import com.firebase.ui.auth.util.SignInPreferenceManager import com.google.firebase.auth.AuthResult @@ -107,12 +106,13 @@ internal suspend fun FirebaseAuthUI.verifyPhoneNumber( provider: AuthProvider.Phone, activity: Activity?, phoneNumber: String, + config: AuthUIConfiguration, multiFactorSession: MultiFactorSession? = null, forceResendingToken: PhoneAuthProvider.ForceResendingToken? = null, verifier: AuthProvider.Phone.Verifier = AuthProvider.Phone.DefaultVerifier(), ) { try { - updateAuthState(AuthState.Loading((activity ?: app.applicationContext).getString(R.string.fui_loading_verifying_phone_number))) + updateAuthState(AuthState.Loading(config.stringProvider.loadingVerifyingPhoneNumber)) val result = provider.verifyPhoneNumberAwait( auth = auth, activity = activity, diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/screens/FirebaseAuthScreen.kt b/auth/src/main/java/com/firebase/ui/auth/ui/screens/FirebaseAuthScreen.kt index 2dfba2fec..ce57fae71 100644 --- a/auth/src/main/java/com/firebase/ui/auth/ui/screens/FirebaseAuthScreen.kt +++ b/auth/src/main/java/com/firebase/ui/auth/ui/screens/FirebaseAuthScreen.kt @@ -986,7 +986,7 @@ private fun FirebaseAuthUI.rememberOnProviderSelected( val twitterProvider = config.providers.filterIsInstance().firstOrNull() val genericOAuthProviders = config.providers.filterIsInstance() - val onSignInAnonymously = anonymousProvider?.let { rememberAnonymousSignInHandler() } + val onSignInAnonymously = anonymousProvider?.let { rememberAnonymousSignInHandler(config) } val onSignInWithGoogle = googleProvider?.let { rememberGoogleSignInHandler(context, config, it) } val onSignInWithFacebook = facebookProvider?.let { rememberSignInWithFacebookLauncher(context, config, it) } val onSignInWithApple = appleProvider?.let { rememberOAuthSignInHandler(context, activity, config, it) } diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/screens/email/EmailAuthScreen.kt b/auth/src/main/java/com/firebase/ui/auth/ui/screens/email/EmailAuthScreen.kt index 2c134c67e..af3949f4e 100644 --- a/auth/src/main/java/com/firebase/ui/auth/ui/screens/email/EmailAuthScreen.kt +++ b/auth/src/main/java/com/firebase/ui/auth/ui/screens/email/EmailAuthScreen.kt @@ -331,6 +331,7 @@ fun EmailAuthScreen( try { authUI.sendPasswordResetEmail( email = emailTextValue.value, + config = configuration, actionCodeSettings = configuration.passwordResetActionCodeSettings, ) } catch (e: Exception) { diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/screens/phone/PhoneAuthScreen.kt b/auth/src/main/java/com/firebase/ui/auth/ui/screens/phone/PhoneAuthScreen.kt index 26161da78..8b3a69c6c 100644 --- a/auth/src/main/java/com/firebase/ui/auth/ui/screens/phone/PhoneAuthScreen.kt +++ b/auth/src/main/java/com/firebase/ui/auth/ui/screens/phone/PhoneAuthScreen.kt @@ -284,6 +284,7 @@ fun PhoneAuthScreen( provider = provider, activity = activity, phoneNumber = fullPhoneNumber, + config = configuration, ) } catch (e: Exception) { // Error will be handled by authState flow @@ -319,6 +320,7 @@ fun PhoneAuthScreen( activity = activity, provider = provider, phoneNumber = fullPhoneNumber, + config = configuration, forceResendingToken = forceResendingToken.value, ) resendTimerSeconds.intValue = provider.timeout.toInt() // Restart timer diff --git a/auth/src/test/java/com/firebase/ui/auth/configuration/auth_provider/AnonymousAuthProviderFirebaseAuthUITest.kt b/auth/src/test/java/com/firebase/ui/auth/configuration/auth_provider/AnonymousAuthProviderFirebaseAuthUITest.kt index 2a3b3c63c..04abdc6fc 100644 --- a/auth/src/test/java/com/firebase/ui/auth/configuration/auth_provider/AnonymousAuthProviderFirebaseAuthUITest.kt +++ b/auth/src/test/java/com/firebase/ui/auth/configuration/auth_provider/AnonymousAuthProviderFirebaseAuthUITest.kt @@ -19,6 +19,7 @@ import androidx.test.core.app.ApplicationProvider import com.firebase.ui.auth.AuthException import com.firebase.ui.auth.AuthState import com.firebase.ui.auth.FirebaseAuthUI +import com.firebase.ui.auth.configuration.AuthUIConfiguration import com.firebase.ui.auth.configuration.authUIConfiguration import com.google.android.gms.tasks.TaskCompletionSource import com.google.common.truth.Truth.assertThat @@ -58,6 +59,7 @@ class AnonymousAuthProviderFirebaseAuthUITest { private lateinit var firebaseApp: FirebaseApp private lateinit var applicationContext: Context + private lateinit var config: AuthUIConfiguration @Before fun setUp() { @@ -79,6 +81,14 @@ class AnonymousAuthProviderFirebaseAuthUITest { .setProjectId("fake-project-id") .build() ) + + config = authUIConfiguration { + context = applicationContext + providers { + provider(AuthProvider.Anonymous) + provider(AuthProvider.Email(emailLinkActionCodeSettings = null, passwordValidationRules = emptyList())) + } + } } @After @@ -108,7 +118,7 @@ class AnonymousAuthProviderFirebaseAuthUITest { val instance = FirebaseAuthUI.create(firebaseApp, mockFirebaseAuth) - instance.signInAnonymously() + instance.signInAnonymously(config) verify(mockFirebaseAuth).signInAnonymously() @@ -124,7 +134,7 @@ class AnonymousAuthProviderFirebaseAuthUITest { val instance = FirebaseAuthUI.create(firebaseApp, mockFirebaseAuth) // Queue signInAnonymously first; first{} suspends and lets the scheduler run it - val job = launch { runCatching { instance.signInAnonymously() } } + val job = launch { runCatching { instance.signInAnonymously(config) } } val loadingState = instance.authStateFlow().first { it is AuthState.Loading } assertThat((loadingState as AuthState.Loading).message) @@ -144,7 +154,7 @@ class AnonymousAuthProviderFirebaseAuthUITest { val instance = FirebaseAuthUI.create(firebaseApp, mockFirebaseAuth) try { - instance.signInAnonymously() + instance.signInAnonymously(config) assertThat(false).isTrue() // Should not reach here } catch (e: AuthException.NetworkException) { assertThat(e.cause).isEqualTo(networkException) @@ -167,7 +177,7 @@ class AnonymousAuthProviderFirebaseAuthUITest { val instance = FirebaseAuthUI.create(firebaseApp, mockFirebaseAuth) try { - instance.signInAnonymously() + instance.signInAnonymously(config) assertThat(false).isTrue() // Should not reach here } catch (e: AuthException.AuthCancelledException) { assertThat(e.message).contains("cancelled") @@ -191,7 +201,7 @@ class AnonymousAuthProviderFirebaseAuthUITest { val instance = FirebaseAuthUI.create(firebaseApp, mockFirebaseAuth) try { - instance.signInAnonymously() + instance.signInAnonymously(config) assertThat(false).isTrue() // Should not reach here } catch (e: AuthException.UnknownException) { assertThat(e.cause).isEqualTo(genericException) diff --git a/auth/src/test/java/com/firebase/ui/auth/configuration/auth_provider/EmailAuthProviderFirebaseAuthUITest.kt b/auth/src/test/java/com/firebase/ui/auth/configuration/auth_provider/EmailAuthProviderFirebaseAuthUITest.kt index e39fc38eb..b06489e3d 100644 --- a/auth/src/test/java/com/firebase/ui/auth/configuration/auth_provider/EmailAuthProviderFirebaseAuthUITest.kt +++ b/auth/src/test/java/com/firebase/ui/auth/configuration/auth_provider/EmailAuthProviderFirebaseAuthUITest.kt @@ -20,6 +20,7 @@ import com.firebase.ui.auth.R import com.firebase.ui.auth.AuthException import com.firebase.ui.auth.AuthState import com.firebase.ui.auth.FirebaseAuthUI +import com.firebase.ui.auth.configuration.AuthUIConfiguration import com.firebase.ui.auth.configuration.PasswordRule import com.firebase.ui.auth.configuration.authUIConfiguration import com.firebase.ui.auth.util.EmailLinkPersistenceManager @@ -82,6 +83,7 @@ class EmailAuthProviderFirebaseAuthUITest { private lateinit var firebaseApp: FirebaseApp private lateinit var applicationContext: Context + private lateinit var emailConfig: AuthUIConfiguration @Before fun setUp() { @@ -103,6 +105,13 @@ class EmailAuthProviderFirebaseAuthUITest { .setProjectId("fake-project-id") .build() ) + + emailConfig = authUIConfiguration { + context = applicationContext + providers { + provider(AuthProvider.Email(emailLinkActionCodeSettings = null, passwordValidationRules = emptyList())) + } + } } @After @@ -817,7 +826,7 @@ class EmailAuthProviderFirebaseAuthUITest { val instance = FirebaseAuthUI.create(firebaseApp, mockFirebaseAuth) - instance.sendPasswordResetEmail("test@example.com") + instance.sendPasswordResetEmail("test@example.com", emailConfig) verify(mockFirebaseAuth).sendPasswordResetEmail( ArgumentMatchers.eq("test@example.com"), @@ -841,7 +850,7 @@ class EmailAuthProviderFirebaseAuthUITest { val instance = FirebaseAuthUI.create(firebaseApp, mockFirebaseAuth) - instance.sendPasswordResetEmail("test@example.com", actionCodeSettings) + instance.sendPasswordResetEmail("test@example.com", emailConfig, actionCodeSettings) verify(mockFirebaseAuth).sendPasswordResetEmail("test@example.com", actionCodeSettings) @@ -865,7 +874,7 @@ class EmailAuthProviderFirebaseAuthUITest { val instance = FirebaseAuthUI.create(firebaseApp, mockFirebaseAuth) try { - instance.sendPasswordResetEmail("test@example.com") + instance.sendPasswordResetEmail("test@example.com", emailConfig) assertThat(false).isTrue() // Should not reach here } catch (e: AuthException.UserNotFoundException) { assertThat(e.cause).isEqualTo(userNotFoundException) @@ -888,7 +897,7 @@ class EmailAuthProviderFirebaseAuthUITest { val instance = FirebaseAuthUI.create(firebaseApp, mockFirebaseAuth) try { - instance.sendPasswordResetEmail("test@example.com") + instance.sendPasswordResetEmail("test@example.com", emailConfig) assertThat(false).isTrue() // Should not reach here } catch (e: AuthException.InvalidCredentialsException) { assertThat(e.cause).isEqualTo(invalidEmailException) @@ -908,7 +917,7 @@ class EmailAuthProviderFirebaseAuthUITest { val instance = FirebaseAuthUI.create(firebaseApp, mockFirebaseAuth) try { - instance.sendPasswordResetEmail("test@example.com") + instance.sendPasswordResetEmail("test@example.com", emailConfig) assertThat(false).isTrue() // Should not reach here } catch (e: AuthException.AuthCancelledException) { assertThat(e.message).contains("cancelled") diff --git a/auth/src/test/java/com/firebase/ui/auth/configuration/auth_provider/PhoneAuthProviderFirebaseAuthUITest.kt b/auth/src/test/java/com/firebase/ui/auth/configuration/auth_provider/PhoneAuthProviderFirebaseAuthUITest.kt index 81386183c..3efe90c5b 100644 --- a/auth/src/test/java/com/firebase/ui/auth/configuration/auth_provider/PhoneAuthProviderFirebaseAuthUITest.kt +++ b/auth/src/test/java/com/firebase/ui/auth/configuration/auth_provider/PhoneAuthProviderFirebaseAuthUITest.kt @@ -18,6 +18,7 @@ import android.content.Context import androidx.test.core.app.ApplicationProvider import com.firebase.ui.auth.AuthState import com.firebase.ui.auth.FirebaseAuthUI +import com.firebase.ui.auth.configuration.AuthUIConfiguration import com.firebase.ui.auth.configuration.authUIConfiguration import com.google.android.gms.tasks.TaskCompletionSource import com.google.common.truth.Truth.assertThat @@ -71,6 +72,7 @@ class PhoneAuthProviderFirebaseAuthUITest { private lateinit var firebaseApp: FirebaseApp private lateinit var applicationContext: Context + private lateinit var phoneConfig: AuthUIConfiguration @Before fun setUp() { @@ -92,6 +94,13 @@ class PhoneAuthProviderFirebaseAuthUITest { .setProjectId("fake-project-id") .build() ) + + phoneConfig = authUIConfiguration { + context = applicationContext + providers { + provider(AuthProvider.Phone(defaultNumber = null, defaultCountryCode = null, allowedCountries = null)) + } + } } @After @@ -136,6 +145,7 @@ class PhoneAuthProviderFirebaseAuthUITest { provider = phoneProvider, activity = null, phoneNumber = "+1234567890", + config = phoneConfig, verifier = mockPhoneAuthVerifier ) @@ -179,6 +189,7 @@ class PhoneAuthProviderFirebaseAuthUITest { provider = phoneProvider, activity = null, phoneNumber = "+1234567890", + config = phoneConfig, verifier = mockPhoneAuthVerifier ) @@ -224,6 +235,7 @@ class PhoneAuthProviderFirebaseAuthUITest { provider = phoneProvider, activity = null, phoneNumber = "+1234567890", + config = phoneConfig, forceResendingToken = mockToken, verifier = mockPhoneAuthVerifier ) @@ -268,6 +280,7 @@ class PhoneAuthProviderFirebaseAuthUITest { provider = phoneProvider, activity = null, phoneNumber = "+1234567890", + config = phoneConfig, verifier = mockPhoneAuthVerifier )