Skip to content

Commit 4785c0e

Browse files
committed
fix(sample): address review feedback on full customization demo
Intercept back on the login/sign-up steps so it returns to email entry instead of leaving the auth flow, make the other-sign-in-methods sheet scrollable (nine providers plus the ToS footer overflow shorter screens), compare the confirmation email trimmed and case-insensitively and give the field an email keyboard, and take the configured FirebaseAuth instance rather than reaching for the global default.
1 parent a2d2bc9 commit 4785c0e

5 files changed

Lines changed: 29 additions & 5 deletions

File tree

app/src/main/java/com/firebaseui/android/demo/auth/fullcustomization/FullCustomizationDemoActivity.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ private fun MainUI(
173173
) { state ->
174174
AuthMethodPickerUI(
175175
state = state,
176+
auth = authUI.auth,
176177
otherProviders = providers.filterNot { it is AuthProvider.Email },
177178
onProviderSelected = onProviderSelected,
178179
tosUrl = configuration.tosUrl,

app/src/main/java/com/firebaseui/android/demo/auth/fullcustomization/common/CtaButton.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ fun CtaButton(
4545
.height(80.dp),
4646
) {
4747
if (isLoading) {
48+
// Left on the M3 default (colorScheme.primary). Every caller passes
49+
// `enabled = ... && !isLoading`, so the button is disabled exactly while the
50+
// spinner shows: the container is the translucent disabled fill, and primary
51+
// reads clearly against it. Using LocalContentColor here would instead pick up
52+
// disabledContentColor (onSurface at 38%) and wash the spinner out.
4853
CircularProgressIndicator(modifier = Modifier.size(20.dp))
4954
} else {
5055
Text(text = text, style = MaterialTheme.typography.titleMedium)

app/src/main/java/com/firebaseui/android/demo/auth/fullcustomization/common/OtherSignInMethodsSheet.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import androidx.compose.foundation.layout.Spacer
66
import androidx.compose.foundation.layout.fillMaxWidth
77
import androidx.compose.foundation.layout.height
88
import androidx.compose.foundation.layout.padding
9+
import androidx.compose.foundation.rememberScrollState
10+
import androidx.compose.foundation.verticalScroll
911
import androidx.compose.material3.ExperimentalMaterial3Api
1012
import androidx.compose.material3.MaterialTheme
1113
import androidx.compose.material3.ModalBottomSheet
@@ -32,9 +34,12 @@ fun OtherSignInMethodsSheet(
3234
onDismissRequest = onDismissRequest,
3335
containerColor = MaterialTheme.colorScheme.primaryContainer,
3436
) {
37+
// Scrollable: the demo offers nine alternative providers plus the ToS footer, which
38+
// overflows a bottom sheet on shorter screens and in landscape.
3539
Column(
3640
modifier = Modifier
3741
.fillMaxWidth()
42+
.verticalScroll(rememberScrollState())
3843
.padding(horizontal = 64.dp),
3944
) {
4045
Text(

app/src/main/java/com/firebaseui/android/demo/auth/fullcustomization/screens/AuthMethodPickerUI.kt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.firebaseui.android.demo.auth.fullcustomization.screens
22

33
import android.util.Log
4+
import androidx.activity.compose.BackHandler
45
import androidx.compose.foundation.layout.Box
56
import androidx.compose.foundation.layout.fillMaxSize
67
import androidx.compose.runtime.Composable
@@ -25,6 +26,7 @@ private enum class FlowStep { EnterEmail, Login, SignUp }
2526
@Composable
2627
fun AuthMethodPickerUI(
2728
state: EmailAuthContentState,
29+
auth: FirebaseAuth,
2830
otherProviders: List<AuthProvider>,
2931
onProviderSelected: (AuthProvider) -> Unit,
3032
tosUrl: String?,
@@ -45,6 +47,10 @@ fun AuthMethodPickerUI(
4547
flowStep = FlowStep.EnterEmail
4648
}
4749

50+
// customMethodPickerLayout is the NavHost's start destination and these steps are local
51+
// state, so without this the system back press would leave the auth flow entirely.
52+
BackHandler(enabled = flowStep != FlowStep.EnterEmail) { onUseDifferentEmail() }
53+
4854
Box(modifier = Modifier.fillMaxSize()) {
4955
when (flowStep) {
5056
FlowStep.EnterEmail -> EmailEntryStep(
@@ -54,7 +60,7 @@ fun AuthMethodPickerUI(
5460
onContinue = {
5561
isCheckingEmail = true
5662
coroutineScope.launch {
57-
val signInMethods = fetchLegacySignInMethods(state.email)
63+
val signInMethods = fetchLegacySignInMethods(auth, state.email)
5864
flowStep = if (signInMethods.isEmpty()) FlowStep.SignUp else FlowStep.Login
5965
isCheckingEmail = false
6066
}
@@ -90,11 +96,10 @@ fun AuthMethodPickerUI(
9096
* deprecated by Firebase ("legacy") and, depending on the project's Email Enumeration Protection
9197
* setting, may always return an empty list regardless of whether the email exists.
9298
*/
93-
private suspend fun fetchLegacySignInMethods(email: String): List<String> {
99+
private suspend fun fetchLegacySignInMethods(auth: FirebaseAuth, email: String): List<String> {
94100
return try {
95101
@Suppress("DEPRECATION")
96-
FirebaseAuth.getInstance()
97-
.fetchSignInMethodsForEmail(email)
102+
auth.fetchSignInMethodsForEmail(email)
98103
.await()
99104
.signInMethods
100105
?.filter { it.isNotBlank() }

app/src/main/java/com/firebaseui/android/demo/auth/fullcustomization/screens/email/pages/SignUpStep.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.padding
1414
import androidx.compose.foundation.layout.safeDrawingPadding
1515
import androidx.compose.foundation.layout.size
1616
import androidx.compose.foundation.rememberScrollState
17+
import androidx.compose.foundation.text.KeyboardOptions
1718
import androidx.compose.foundation.shape.RoundedCornerShape
1819
import androidx.compose.foundation.verticalScroll
1920
import androidx.compose.material3.MaterialTheme
@@ -29,6 +30,7 @@ import androidx.compose.ui.Modifier
2930
import androidx.compose.ui.res.painterResource
3031
import androidx.compose.ui.semantics.contentDescription
3132
import androidx.compose.ui.semantics.semantics
33+
import androidx.compose.ui.text.input.KeyboardType
3234
import androidx.compose.ui.text.input.PasswordVisualTransformation
3335
import androidx.compose.ui.unit.dp
3436
import com.firebase.ui.auth.ui.screens.email.EmailAuthContentState
@@ -61,7 +63,10 @@ fun SignUpStep(
6163
var lastName by remember { mutableStateOf("") }
6264
var confirmEmail by remember { mutableStateOf("") }
6365

64-
val emailsMatch = confirmEmail.isNotBlank() && confirmEmail == state.email
66+
// Compared case-insensitively and trimmed: this field uses the default keyboard, which
67+
// auto-capitalises on many IMEs, so an exact match would reject the user's own address.
68+
val emailsMatch = confirmEmail.isNotBlank() &&
69+
confirmEmail.trim().equals(state.email.trim(), ignoreCase = true)
6570
val passwordsMatch = state.confirmPassword.isNotBlank() && state.confirmPassword == state.password
6671
val canSignUp = firstName.isNotBlank() &&
6772
lastName.isNotBlank() &&
@@ -153,6 +158,9 @@ fun SignUpStep(
153158
onValueChange = { confirmEmail = it },
154159
label = "Confirm Email",
155160
enabled = !state.isLoading,
161+
keyboardOptions = KeyboardOptions(
162+
keyboardType = KeyboardType.Email,
163+
),
156164
isError = confirmEmail.isNotBlank() && !emailsMatch,
157165
supportingText = if (confirmEmail.isNotBlank() && !emailsMatch) {
158166
"Emails don't match"

0 commit comments

Comments
 (0)