### Install and Run Example App via Gradle Source: https://github.com/firebase/firebaseui-android/blob/master/CONTRIBUTING.md Install the example application on a connected device or emulator using Gradle. Changes to library modules will be reflected automatically. ```bash ./gradlew :app:installDebug ``` -------------------------------- ### Setup and Run E2E Tests Source: https://github.com/firebase/firebaseui-android/blob/master/CONTRIBUTING.md Install Firebase Tools, start the Firebase Auth Emulator, and then run the end-to-end tests. These tests validate integration with Firebase services. ```bash # Install Firebase Tools (if not already installed) ``` ```bash npm install -g firebase-tools ``` ```bash # Start the Firebase Auth Emulator ``` ```bash ./scripts/start-firebase-emulator.sh ``` ```bash ./gradlew e2eTest ``` -------------------------------- ### Build and Verify Environment Setup Source: https://github.com/firebase/firebaseui-android/blob/master/CONTRIBUTING.md Run this script to verify your development environment setup. It builds all modules, runs checkstyle, and executes unit tests. ```bash ./scripts/build.sh ``` -------------------------------- ### Minimal FirebaseUI Authentication Example Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Sets up Email and Google Sign-In providers for a complete authentication flow. Ensure Firebase is initialized and configured. ```kotlin class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MyAppTheme { val configuration = authUIConfiguration { providers { provider(AuthProvider.Email()) provider(AuthProvider.Google()) } } FirebaseAuthScreen( configuration = configuration, onSignInSuccess = { result -> Toast.makeText(this, "Welcome!", Toast.LENGTH_SHORT).show() // Navigate to main app screen }, onSignInFailure = { exception -> Toast.makeText(this, "Error: ${exception.message}", Toast.LENGTH_SHORT).show() }, onSignInCancelled = { finish() } ) } } } } ``` -------------------------------- ### Install Locally with Gradle Source: https://github.com/firebase/firebaseui-android/blob/master/README.md Run this command in your project's root directory to download FirebaseUI and prepare artifacts for local installation. ```sh ./gradlew :library:prepareArtifacts publishToMavenLocal ``` -------------------------------- ### Configure AuthUI Providers Source: https://github.com/firebase/firebaseui-android/blob/master/GETTING_STARTED.md Set up the desired authentication providers within the authUIConfiguration block. This example shows how to enable Email, Phone, Google, and Facebook sign-in. ```kotlin val configuration = authUIConfiguration { context = applicationContext providers { provider(AuthProvider.Email()) provider( AuthProvider.Phone( defaultCountryCode = "US", ) ) provider( AuthProvider.Google( scopes = listOf("email"), serverClientId = null, ) ) provider(AuthProvider.Facebook()) } } ``` -------------------------------- ### Jetpack Compose SignInScreen Example Source: https://github.com/firebase/firebaseui-android/blob/master/CONTRIBUTING.md A Composable function for a sign-in screen using Jetpack Compose. It includes state management for email and password fields. ```kotlin @Composable fun SignInScreen( configuration: AuthUIConfiguration, onSignInSuccess: (AuthResult) -> Unit, modifier: Modifier = Modifier ) { var email by remember { mutableStateOf("") } var password by remember { mutableStateOf("") } Column( modifier = modifier .fillMaxSize() .padding(16.dp) ) { OutlinedTextField( value = email, onValueChange = { email = it }, label = { Text("Email") }, modifier = Modifier.fillMaxWidth() ) Spacer(modifier = Modifier.height(8.dp)) OutlinedTextField( value = password, onValueChange = { password = it }, label = { Text("Password") }, visualTransformation = PasswordVisualTransformation(), modifier = Modifier.fillMaxWidth() ) } } ``` -------------------------------- ### Start Listening for Data Source: https://github.com/firebase/firebaseui-android/blob/master/firestore/README.md Call startListening() in your Activity or Fragment's onStart() method to begin receiving real-time updates from Firestore. Ensure authentication is complete before calling. ```java @Override protected void onStart() { super.onStart(); adapter.startListening(); } ``` -------------------------------- ### Implement AuthFlowController for Custom Authentication Flow Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Use AuthFlowController to manage the authentication lifecycle. This example demonstrates creating and starting the flow, handling various authentication states like success, error, MFA, email verification, and cancellation. Ensure to dispose of the controller when done. ```kotlin class AuthActivity : ComponentActivity() { private lateinit var controller: AuthFlowController override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val authUI = FirebaseAuthUI.getInstance() val configuration = authUIConfiguration { providers { provider(AuthProvider.Email()) provider(AuthProvider.Google()) } } controller = authUI.createAuthFlow(configuration) lifecycleScope.launch { val state = controller.start() handleAuthState(state) } } private fun handleAuthState(state: AuthState) { when (state) { is AuthState.Success -> { // Successfully signed in val user = state.result.user startActivity(Intent(this, MainActivity::class.java)) finish() } is AuthState.Error -> { // Handle error AlertDialog.Builder(this) .setTitle("Authentication Failed") .setMessage(state.exception.message) .setPositiveButton("OK", null) .show() } is AuthState.RequiresMfa -> { // User needs to complete MFA challenge showMfaChallengeDialog(state.resolver) } is AuthState.RequiresEmailVerification -> { // Email verification needed showEmailVerificationScreen(state.user) } is AuthState.Cancelled -> { // User cancelled authentication finish() } else -> { // Handle other states } } } override fun onDestroy() { super.onDestroy() controller.dispose() } } ``` -------------------------------- ### Convert XML Themes to AuthUITheme in Kotlin Source: https://github.com/firebase/firebaseui-android/blob/master/docs/upgrade-to-10.0.md Migrate your XML-based themes to Kotlin code using `AuthUITheme` for UI customization. This example shows how to define a light color scheme. ```kotlin val configuration = authUIConfiguration { theme = AuthUITheme( colorScheme = lightColorScheme( primary = Color(0xFF6200EE), // ... other colors ) ) } ``` -------------------------------- ### KDoc for signInWithEmailAndPassword Source: https://github.com/firebase/firebaseui-android/blob/master/CONTRIBUTING.md Documentation for the `signInWithEmailAndPassword` suspend function. Includes parameters, return value, exceptions, and an example usage. ```kotlin /** * Authenticates a user with email and password. * * @param email The user's email address * @param password The user's password * @return [AuthResult] containing the signed-in user * @throws AuthException.InvalidCredentialsException if credentials are invalid * @throws AuthException.NetworkException if network is unavailable * * Example usage: * ```kotlin * val result = authUI.signInWithEmailAndPassword( * email = "user@example.com", * password = "securePassword123" * ) * ``` */ suspend fun signInWithEmailAndPassword( email: String, password: String ): AuthResult ``` -------------------------------- ### Conventional Commits Example Source: https://github.com/firebase/firebaseui-android/blob/master/CONTRIBUTING.md Follow the Conventional Commits specification for naming pull request titles. Examples are provided for fixes and new features. ```bash fix(auth): fixed a bug with email sign-in! ``` ```bash feat(auth): add support for passkey authentication ``` -------------------------------- ### Get FirebaseAuthUI Instance Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Demonstrates how to obtain the default or a custom instance of FirebaseAuthUI, including options for multi-tenancy. ```kotlin // Get the default instance val authUI = FirebaseAuthUI.getInstance() // Or get an instance for a specific Firebase app val customApp = Firebase.app("secondary") val authUI = FirebaseAuthUI.getInstance(customApp) // Or create with custom auth (for multi-tenancy) val customAuth = Firebase.auth(customApp) val authUI = FirebaseAuthUI.create(auth = customAuth) ``` -------------------------------- ### Firebase Data Ordering Example Source: https://github.com/firebase/firebaseui-android/blob/master/database/README.md Illustrates how data ordering is influenced by key order, not data order. Use this to understand how to structure your data for predictable retrieval. ```json { "data": { // This order doesn't matter, the order is taken from keys/(user1 or user2). "3": true, "1": "some data", "2": 5 }, "keys": { // These two users have different orders for their data thanks to key side ordering. "user1": { "1": true, "2": true, "3": true }, "user2": { "3": true, "2": true, "1": true } } } ``` -------------------------------- ### Migrate Activity-based to Compose-based FirebaseUI Auth Source: https://github.com/firebase/firebaseui-android/blob/master/docs/upgrade-to-10.0.md Compares the old View-based Activity setup with the new Compose-based setup for FirebaseUI Auth. The Compose version uses `setContent` and a `FirebaseAuthScreen` composable. ```java public class SignInActivity extends AppCompatActivity { private final ActivityResultLauncher signInLauncher = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), result -> { IdpResponse response = IdpResponse.fromResultIntent(result.getData()); if (result.getResultCode() == RESULT_OK) { FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser(); // User signed in } else { // Sign in failed } } ); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_signin); Intent signInIntent = AuthUI.getInstance() .createSignInIntentBuilder() .setAvailableProviders(Arrays.asList( new AuthUI.IdpConfig.EmailBuilder().build(), new AuthUI.IdpConfig.GoogleBuilder().build() )) .setTheme(R.style.AppTheme) .build(); signInLauncher.launch(signInIntent); } } ``` ```kotlin class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MyAppTheme { val configuration = authUIConfiguration { providers = listOf( AuthProvider.Email(), AuthProvider.Google() ) theme = AuthUITheme.fromMaterialTheme() } FirebaseAuthScreen( configuration = configuration, onSignInSuccess = { result -> val user = result.user // User signed in }, onSignInFailure = { exception -> // Sign in failed }, onSignInCancelled = { finish() } ) } } } } ``` -------------------------------- ### Create Completely Custom Theme Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Build a theme from scratch by defining custom color schemes, typography, shapes, and provider button styles for full control. ```kotlin val customTheme = AuthUITheme( colorScheme = darkColorScheme( primary = Color(0xFF6200EE), onPrimary = Color.White, primaryContainer = Color(0xFF3700B3), secondary = Color(0xFF03DAC6) ), typography = Typography( displayLarge = TextStyle(fontSize = 57.sp, fontWeight = FontWeight.Bold), bodyLarge = TextStyle(fontSize = 16.sp) ), shapes = Shapes( small = RoundedCornerShape(4.dp), medium = RoundedCornerShape(8.dp), large = RoundedCornerShape(16.dp) ), providerButtonShape = RoundedCornerShape(12.dp) ) val configuration = authUIConfiguration { providers { provider(AuthProvider.Email()) } theme = customTheme } ``` -------------------------------- ### Prepare and Publish Artifacts Source: https://github.com/firebase/firebaseui-android/blob/master/docs/internal/releasing.md Clean the project, prepare the artifacts for publishing, and then publish all publications to the Maven repository. This command initiates the release process. ```shell ./gradlew clean :library:prepareArtifacts ./gradlew --no-daemon --no-parallel publishAllPublicationsToMavenRepository ``` -------------------------------- ### Configure DatabasePagingOptions Source: https://github.com/firebase/firebaseui-android/blob/master/database/README.md Configure the adapter by building DatabasePagingOptions, combining paging configuration with query information and lifecycle options. ```java // The "base query" is a query with no startAt/endAt/limit clauses that the adapter can use // to form smaller queries for each page. Query baseQuery = mDatabase.getReference().child("items"); // This configuration comes from the Paging 3 Library // https://developer.android.com/reference/kotlin/androidx/paging/PagingConfig PagingConfig config = new PagingConfig(/* page size */ 20, /* prefetchDistance */ 10, /* enablePlaceHolders */ false); // The options for the adapter combine the paging configuration with query information // and application-specific options for lifecycle, etc. DatabasePagingOptions options = new DatabasePagingOptions.Builder() .setLifecycleOwner(this) .setQuery(baseQuery, config, Item.class) .build(); ``` -------------------------------- ### Configure Google Sign-In Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Integrate Google Sign-In by specifying required scopes and an optional server client ID for backend authentication. Custom OAuth parameters can also be provided. ```kotlin val googleProvider = AuthProvider.Google( // Required: Scopes to request scopes = listOf("https://www.googleapis.com/auth/drive.file"), // Optional: Server client ID for backend authentication serverClientId = "YOUR_SERVER_CLIENT_ID.apps.googleusercontent.com", // Optional: Custom OAuth parameters customParameters = mapOf("prompt" to "select_account") ) val configuration = authUIConfiguration { providers { provider(googleProvider) } } ``` -------------------------------- ### Configure and Show Firebase Auth UI Source: https://github.com/firebase/firebaseui-android/blob/master/GETTING_STARTED.md Set up the AuthUI configuration with desired providers and themes, then display the authentication screen. Handles sign-in success, failure, and cancellation callbacks. ```kotlin class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val authUI = FirebaseAuthUI.getInstance() setContent { MyAppTheme { val configuration = authUIConfiguration { context = applicationContext theme = AuthUITheme.fromMaterialTheme() providers { provider(AuthProvider.Email()) provider( AuthProvider.Google( scopes = listOf("email"), serverClientId = null, ) ) } } if (authUI.isSignedIn()) { HomeScreen() } else { FirebaseAuthScreen( configuration = configuration, authUI = authUI, onSignInSuccess = { result -> // User signed in successfully }, onSignInFailure = { exception -> // Sign in failed }, onSignInCancelled = { finish() }, ) } } } } } ``` -------------------------------- ### Run Full CI Build Script Source: https://github.com/firebase/firebaseui-android/blob/master/CONTRIBUTING.md Execute the main build script to clean, assemble, check style, and run unit tests. Individual commands can also be run separately. ```bash ./scripts/build.sh ``` -------------------------------- ### Configure FirestorePagingOptions Source: https://github.com/firebase/firebaseui-android/blob/master/firestore/README.md Configure the adapter by building FirestorePagingOptions, including the base query, PagingConfig, and model class. Ensure the base query has only orderBy() and where() clauses. ```java Query baseQuery = mItemsCollection.orderBy("value", Query.Direction.ASCENDING); PagingConfig config = new PagingConfig(/* page size */ 20, /* prefetchDistance */ 10, /* enablePlaceHolders */ false); FirestorePagingOptions options = new FirestorePagingOptions.Builder() .setLifecycleOwner(this) .setQuery(baseQuery, config, Item.class) .build(); ``` -------------------------------- ### Theme Precedence: Ultimate Fallback Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Illustrates the ultimate fallback theme (AuthUITheme.Default) when neither configuration nor wrapper specifies a theme. ```kotlin val configuration = authUIConfiguration { // theme not specified (null) } FirebaseAuthScreen(configuration, ...) // No wrapper // Result: Uses AuthUITheme.Default (light theme) ``` -------------------------------- ### Listening to Firestore Query Updates Source: https://github.com/firebase/firebaseui-android/blob/master/firestore/README.md Use addSnapshotListener to receive real-time updates for a Firestore query. This example shows how to convert the snapshot to a list of Chat objects and update the UI. ```java query.addSnapshotListener(new EventListener() { @Override public void onEvent(@Nullable QuerySnapshot snapshot, @Nullable FirebaseFirestoreException e) { if (e != null) { // Handle error //... return; } // Convert query snapshot to a list of chats List chats = snapshot.toObjects(Chat.class); // Update UI // ... } }); ``` -------------------------------- ### Theme Precedence: Wrapper as Fallback Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Shows how the AuthUITheme wrapper acts as a fallback when the theme is not specified in the configuration. ```kotlin val configuration = authUIConfiguration { // theme not specified (null) } AuthUITheme(theme = AuthUITheme.DefaultDark) { // DARK wrapper FirebaseAuthScreen(configuration, ...) } // Result: FirebaseAuthScreen inherits DARK theme from wrapper ``` -------------------------------- ### MFA Enrollment with Custom UI Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Provides a way to implement custom UI for each step of the MFA enrollment process, allowing for a fully tailored user experience. ```kotlin MfaEnrollmentScreen( user = currentUser, configuration = mfaConfig, onEnrollmentComplete = { /* ... */ }, onSkip = { /* ... */ } ) { state -> when (state.step) { MfaEnrollmentStep.SelectFactor -> { CustomFactorSelectionUI(state) } MfaEnrollmentStep.ConfigureSms -> { CustomSmsConfigurationUI(state) } MfaEnrollmentStep.ConfigureTotp -> { CustomTotpConfigurationUI(state) } MfaEnrollmentStep.VerifyFactor -> { CustomVerificationUI(state) } MfaEnrollmentStep.ShowRecoveryCodes -> { CustomRecoveryCodesUI(state) } } } ``` -------------------------------- ### Theme Precedence: Configuration Over Wrapper Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Demonstrates that the theme specified in the authUIConfiguration takes precedence over a theme set in an AuthUITheme wrapper. ```kotlin val configuration = authUIConfiguration { theme = AuthUITheme.Default // LIGHT theme } AuthUITheme(theme = AuthUITheme.DefaultDark) { // DARK wrapper FirebaseAuthScreen(configuration, ...) } // Result: FirebaseAuthScreen uses LIGHT theme (from configuration) ``` -------------------------------- ### Configure Gradle Properties for Publishing Source: https://github.com/firebase/firebaseui-android/blob/master/docs/internal/releasing.md Set up your local Gradle properties file with GPG and Sonatype credentials. This is required for signing and publishing artifacts. ```properties signing.keyId= signing.password= signing.secretKeyRingFile= mavenCentralUsername= mavenCentralPassword= ``` -------------------------------- ### Configure Other OAuth Providers Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Set up authentication for Twitter, GitHub, Microsoft, Yahoo, and Apple. Each provider may require specific parameters like custom OAuth parameters, scopes, or tenant IDs. ```kotlin // Twitter val twitterProvider = AuthProvider.Twitter( // Required: Custom OAuth parameters customParameters = mapOf("lang" to "en") ) // GitHub val githubProvider = AuthProvider.Github( // Optional: Scopes to request (default: ["user:email"]) scopes = listOf("user:email", "read:user"), // Required: Custom OAuth parameters customParameters = mapOf("allow_signup" to "false") ) // Microsoft val microsoftProvider = AuthProvider.Microsoft( // Optional: Scopes to request (default: ["openid", "profile", "email"]) scopes = listOf("openid", "profile", "email", "User.Read"), // Optional: Tenant ID for Azure Active Directory tenant = "YOUR_TENANT_ID", // Required: Custom OAuth parameters customParameters = mapOf("prompt" to "consent") ) // Yahoo val yahooProvider = AuthProvider.Yahoo( // Optional: Scopes to request (default: ["openid", "profile", "email"]) scopes = listOf("openid", "profile", "email"), // Required: Custom OAuth parameters customParameters = mapOf("language" to "en-us") ) // Apple val appleProvider = AuthProvider.Apple( // Optional: Scopes to request (default: ["name", "email"]) scopes = listOf("name", "email"), // Optional: Locale for the sign-in page locale = "en_US", // Required: Custom OAuth parameters customParameters = mapOf("ui_locales" to "en-US") ) val configuration = authUIConfiguration { providers { provider(twitterProvider) provider(githubProvider) provider(microsoftProvider) provider(yahooProvider) provider(appleProvider) } } ``` -------------------------------- ### Using Adaptive AuthUI Theme Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Set the theme to `AuthUITheme.Adaptive` to automatically switch between light and dark modes based on system settings. This is the recommended approach. ```kotlin val configuration = authUIConfiguration { providers { provider(AuthProvider.Email()) provider(AuthProvider.Google()) } theme = AuthUITheme.Adaptive // Adapts to system dark mode } ``` -------------------------------- ### Import authUIConfiguration Source: https://github.com/firebase/firebaseui-android/blob/master/docs/upgrade-to-10.0.md Ensure this import is present to resolve 'authUIConfiguration' references. ```kotlin import com.firebase.ui.auth.configuration.authUIConfiguration ``` -------------------------------- ### License Header for New Files Source: https://github.com/firebase/firebaseui-android/blob/master/CONTRIBUTING.md Include this license header at the beginning of all new files. It specifies the copyright and licensing information for the project. ```java /* * Copyright 2025 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ ``` -------------------------------- ### Configure Facebook Login Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Set up Facebook Login, optionally requesting specific permissions beyond the default 'email' and 'public_profile'. Custom OAuth parameters like 'display' can also be configured. ```kotlin val facebookProvider = AuthProvider.Facebook( // Optional: Permissions to request (default: ["email", "public_profile"]) scopes = listOf("email", "public_profile", "user_friends"), // Optional: Custom OAuth parameters customParameters = mapOf("display" to "popup") ) val configuration = authUIConfiguration { providers { provider(facebookProvider) } } ``` -------------------------------- ### MFA Enrollment with Default UI Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Use this composable to prompt users to enroll in MFA after sign-in. It supports SMS and TOTP factors by default. ```kotlin import com.google.firebase.auth.FirebaseAuth import com.google.firebase.auth.ktx.auth import androidx.compose.runtime.Composable import android.widget.Toast import androidx.compose.ui.platform.LocalContext @Composable fun MfaEnrollmentFlow() { val currentUser = FirebaseAuth.getInstance().currentUser val context = LocalContext.current if (currentUser != null) { val mfaConfig = MfaConfiguration( allowedFactors = listOf(MfaFactor.Sms, MfaFactor.Totp) ) MfaEnrollmentScreen( user = currentUser, configuration = mfaConfig, onEnrollmentComplete = { Toast.makeText(context, "MFA enrolled successfully!", Toast.LENGTH_SHORT).show() navigateToHome() }, onSkip = { navigateToHome() } ) } } ``` -------------------------------- ### Enable Email Link Sign-In Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Configure the Email AuthProvider to enable email link sign-in. Requires setting up action code settings for deep link handling. ```kotlin val emailProvider = AuthProvider.Email( isEmailLinkSignInEnabled = true, emailLinkActionCodeSettings = actionCodeSettings { url = "https://example.com/auth" handleCodeInApp = true setAndroidPackageName(packageName, true, "12") }, passwordValidationRules = emptyList() ) val configuration = authUIConfiguration { providers { provider(emailProvider) } } ``` -------------------------------- ### Migrate Email Provider Configuration from 9.x to 10.x Source: https://github.com/firebase/firebaseui-android/blob/master/docs/upgrade-to-10.0.md Compare the old (9.x) and new (10.x) configurations for the Email provider. The new API uses a more declarative Kotlin syntax. ```java new AuthUI.IdpConfig.EmailBuilder() .setRequireName(true) .setAllowNewAccounts(true) .enableEmailLinkSignIn() .setActionCodeSettings(actionCodeSettings) .build() ``` ```kotlin AuthProvider.Email( isDisplayNameRequired = true, isNewAccountsAllowed = true, isEmailLinkSignInEnabled = true, emailLinkActionCodeSettings = actionCodeSettings { url = "https://example.com/auth" handleCodeInApp = true setAndroidPackageName(packageName, true, null) } ) ``` -------------------------------- ### Create Release Branch Source: https://github.com/firebase/firebaseui-android/blob/master/docs/internal/releasing.md Checkout the latest development branch and create a new release branch from its HEAD. This is the first step in preparing a new version for release. ```shell $VERSION=1.2.3 $ git checkout version-$VERSION-dev && git pull origin version-$VERSION-dev $ git checkout -b version-$VERSION ``` -------------------------------- ### Configure FirebaseUI Auth Providers and Theme Source: https://github.com/firebase/firebaseui-android/blob/master/GETTING_STARTED.md Set up authentication providers (Email, Google) and the UI theme (Adaptive) for FirebaseUI. This configuration is used within `authUIConfiguration`. ```kotlin val configuration = authUIConfiguration { context = applicationContext providers { provider(AuthProvider.Email()) provider(AuthProvider.Google(scopes = listOf("email"), serverClientId = null)) } theme = AuthUITheme.Adaptive } ``` -------------------------------- ### Configure Scale Animations for Auth UI Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Combine fadeIn, fadeOut, scaleIn, and scaleOut within AuthUITransitions for combined fade and scale screen effects. Note the initialScale and targetScale parameters. ```kotlin import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.scaleIn import androidx.compose.animation.scaleOut import com.firebase.ui.auth.configuration.AuthUITransitions val configuration = authUIConfiguration { providers { provider(AuthProvider.Facebook()) } transitions = AuthUITransitions( enterTransition = { fadeIn() + scaleIn(initialScale = 0.9f) }, exitTransition = { fadeOut() + scaleOut(targetScale = 0.9f) }, popEnterTransition = { fadeIn() + scaleIn(initialScale = 0.9f) }, popExitTransition = { fadeOut() + scaleOut(targetScale = 0.9f) } ) } ``` -------------------------------- ### Theme in Configuration Only Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Set the theme directly within the authUIConfiguration. This is the recommended approach for most use cases due to its simplicity and explicitness. ```kotlin val configuration = authUIConfiguration { context = applicationContext providers { provider(AuthProvider.Email()) } theme = AuthUITheme.Adaptive // Set theme here } FirebaseAuthScreen( configuration = configuration, onSignInSuccess = { /* ... */ } ) ``` -------------------------------- ### Manual MFA Challenge Resolution Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Manually handle MFA challenges using `MfaChallengeScreen` and resolve the sign-in process with the provided assertion. ```kotlin import androidx.compose.runtime.Composable import com.google.firebase.auth.MultiFactorResolver import androidx.lifecycle.lifecycleScope import kotlinx.coroutines.launch @Composable fun ManualMfaChallenge(resolver: MultiFactorResolver) { MfaChallengeScreen( resolver = resolver, onChallengeComplete = { // Complete sign-in with the assertion lifecycleScope.launch { try { val result = resolver.resolveSignIn(assertion) navigateToHome() } catch (e: Exception) { showError(e) } } }, onCancel = { navigateBack() } ) } ``` -------------------------------- ### FirebaseUI Auth 10.x Compose-based Sign-In Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Demonstrates the new approach for initiating a sign-in flow using Compose with FirebaseUI Auth 10.x. Configuration is done via a DSL, and callbacks are handled directly. ```kotlin val configuration = authUIConfiguration { providers { provider(AuthProvider.Email()) provider(AuthProvider.Google()) } theme = AuthUITheme.fromMaterialTheme() } FirebaseAuthScreen( configuration = configuration, onSignInSuccess = { result -> /* ... */ }, onSignInFailure = { exception -> /* ... */ }, onSignInCancelled = { /* ... */ } ) ``` -------------------------------- ### Configure AuthUI Settings Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Define authentication providers, theme, and policy URLs using the AuthUIConfiguration builder. Customize app logo, MFA, Credential Manager, and user upgrade settings. ```kotlin val configuration = authUIConfiguration { // Required: Authentication providers providers { provider(AuthProvider.Email()) provider(AuthProvider.Google()) provider(AuthProvider.Phone()) } // Optional: Theme configuration theme = AuthUITheme.fromMaterialTheme() // Optional: Terms of Service and Privacy Policy URLs tosUrl = "https://example.com/terms" privacyPolicyUrl = "https://example.com/privacy" // Optional: App logo logo = Icons.Default.AccountCircle // Optional: Enable MFA (default: true) isMfaEnabled = true // Optional: Enable Credential Manager (default: true) isCredentialManagerEnabled = true // Optional: Allow anonymous user upgrade (default: false) isAnonymousUpgradeEnabled = true // Optional: Require display name on sign-up (default: true) isDisplayNameRequired = true // Optional: Allow new email accounts (default: true) isNewEmailAccountsAllowed = true // Optional: Always show provider choice even with one provider (default: false) isProviderChoiceAlwaysShown = false // Optional: Custom string provider for localization stringProvider = MyCustomStringProvider() // Optional: Locale override locale = Locale.FRENCH } ``` -------------------------------- ### Listen to Load State Changes in Java Source: https://github.com/firebase/firebaseui-android/blob/master/database/README.md Use `addLoadStateListener` to observe loading and error states for pagination. Call `retry()` on error to reattempt the load. ```java adapter.addLoadStateListener(new Function1() { @Override public Unit invoke(CombinedLoadStates states) { LoadState refresh = states.getRefresh(); LoadState append = states.getAppend(); if (refresh instanceof LoadState.Error || append instanceof LoadState.Error) { // The previous load (either initial or additional) failed. Call // the retry() method in order to retry the load operation. // ... } if (refresh instanceof LoadState.Loading) { // The initial Load has begun // ... } if (append instanceof LoadState.Loading) { // The adapter has started to load an additional page // ... } if (append instanceof LoadState.NotLoading) { LoadState.NotLoading notLoading = (LoadState.NotLoading) append; if (notLoading.getEndOfPaginationReached()) { // The adapter has finished loading all of the data set // ... return null; } if (refresh instanceof LoadState.NotLoading) { // The previous load (either initial or additional) completed // ... return null; } } return null; } }); ``` -------------------------------- ### AuthUIConfiguration DSL Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Configure all settings for your authentication flow using the AuthUIConfiguration DSL builder. ```APIDOC ## AuthUIConfiguration `AuthUIConfiguration` defines all settings for your authentication flow. Use the DSL builder function for easy configuration: ```kotlin val configuration = authUIConfiguration { // Required: Authentication providers providers { provider(AuthProvider.Email()) provider(AuthProvider.Google()) provider(AuthProvider.Phone()) } // Optional: Theme configuration theme = AuthUITheme.fromMaterialTheme() // Optional: Terms of Service and Privacy Policy URLs tosUrl = "https://example.com/terms" privacyPolicyUrl = "https://example.com/privacy" // Optional: App logo logo = Icons.Default.AccountCircle // Optional: Enable MFA (default: true) isMfaEnabled = true // Optional: Enable Credential Manager (default: true) isCredentialManagerEnabled = true // Optional: Allow anonymous user upgrade (default: false) isAnonymousUpgradeEnabled = true // Optional: Require display name on sign-up (default: true) isDisplayNameRequired = true // Optional: Allow new email accounts (default: true) isNewEmailAccountsAllowed = true // Optional: Always show provider choice even with one provider (default: false) isProviderChoiceAlwaysShown = false // Optional: Custom string provider for localization stringProvider = MyCustomStringProvider() // Optional: Locale override locale = Locale.FRENCH } ``` ``` -------------------------------- ### Upload GPG Key to Keyserver Source: https://github.com/firebase/firebaseui-android/blob/master/docs/internal/releasing.md Upload your public GPG key to a public keyserver. You may need to verify your email address via a link sent by the keyserver. ```shell gpg --keyserver hkp://keys.openpgp.org --send-keys ``` -------------------------------- ### Run All Unit Tests Source: https://github.com/firebase/firebaseui-android/blob/master/CONTRIBUTING.md Execute unit tests for all modules except `e2eTest`. This command ensures the core logic of the library is functioning correctly. ```bash ./gradlew testDebugUnitTest -x :e2eTest:testDebugUnitTest ``` -------------------------------- ### Create FirestorePagingAdapter Source: https://github.com/firebase/firebaseui-android/blob/master/firestore/README.md Create an instance of FirestorePagingAdapter, providing the configured options and implementing ViewHolder creation and item binding. ```java FirestorePagingAdapter adapter = new FirestorePagingAdapter(options) { @NonNull @Override public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { // Create the ItemViewHolder // ... } @Override protected void onBindViewHolder(@NonNull ItemViewHolder holder, int position, @NonNull Item model) { // Bind the item to the view holder // ... } }; ``` -------------------------------- ### Check Authentication State (Imperative) Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Checks if a user is already signed in before displaying the authentication UI. Navigates to the main app if signed in. ```kotlin class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val authUI = FirebaseAuthUI.getInstance() if (authUI.isSignedIn()) { // User is already signed in, navigate to main app startActivity(Intent(this, MainAppActivity::class.java)) finish() } else { // Show authentication UI setContent { FirebaseAuthScreen(/* ... */) } } } } ``` -------------------------------- ### FirebaseUI Auth 9.x View-based Sign-In Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Illustrates the old approach for initiating a sign-in flow using `startActivityForResult` with FirebaseUI Auth 9.x. Requires setting up an `ActivityResultLauncher` to handle the result. ```java Intent signInIntent = AuthUI.getInstance() .createSignInIntentBuilder() .setAvailableProviders(Arrays.asList( new AuthUI.IdpConfig.EmailBuilder().build(), new AuthUI.IdpConfig.GoogleBuilder().build() )) .setTheme(R.style.AppTheme) .build(); signInLauncher.launch(signInIntent); ``` -------------------------------- ### Configure Phone Number Authentication Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Set up phone number authentication with SMS verification. You can specify default country codes, allowed countries, SMS code length, delivery timeout, and enable instant verification. ```kotlin val phoneProvider = AuthProvider.Phone( // Optional: Default phone number in international format defaultNumber = "+15551234567", // Optional: Default country code (ISO alpha-2 format) defaultCountryCode = "US", // Optional: Allowed countries allowedCountries = listOf("US", "CA", "GB"), // Optional: SMS code length (default: 6) smsCodeLength = 6, // Optional: Timeout for SMS delivery in seconds (default: 60) timeout = 60L, // Optional: Enable instant verification (default: true) isInstantVerificationEnabled = true ) val configuration = authUIConfiguration { providers { provider(phoneProvider) } } ``` -------------------------------- ### MFA Configuration Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Configure Multi-Factor Authentication settings, including allowed factors, whether enrollment is required, and if recovery codes are enabled. This snippet also shows enabling MFA within the overall auth UI configuration. ```kotlin val mfaConfig = MfaConfiguration( // Allowed MFA factors (default: [Sms, Totp]) allowedFactors = listOf(MfaFactor.Sms, MfaFactor.Totp), // Optional: Require MFA enrollment (default: false) requireEnrollment = false, // Optional: Enable recovery codes (default: true) enableRecoveryCodes = true ) val configuration = authUIConfiguration { providers { provider(AuthProvider.Email()) } isMfaEnabled = true } ``` -------------------------------- ### Configure Slide Animations for Auth UI Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Use AuthUITransitions with slideInHorizontally and slideOutHorizontally for custom screen transitions. Default fade animations are used if not specified. ```kotlin import androidx.compose.animation.slideInHorizontally import androidx.compose.animation.slideOutHorizontally import com.firebase.ui.auth.configuration.AuthUITransitions val configuration = authUIConfiguration { providers { provider(AuthProvider.Email()) provider(AuthProvider.Google()) } transitions = AuthUITransitions( enterTransition = { slideInHorizontally { it } }, // Slide in from right exitTransition = { slideOutHorizontally { -it } }, // Slide out to left popEnterTransition = { slideInHorizontally { -it } }, // Slide in from left popExitTransition = { slideOutHorizontally { it } } // Slide out to right ) } ``` -------------------------------- ### Observe Authentication State (Reactive) Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Observes authentication state changes reactively using a Composable function. Shows the main app screen or authentication UI based on the state. ```kotlin @Composable fun AuthGate() { val authUI = remember { FirebaseAuthUI.getInstance() } val authState by authUI.authStateFlow().collectAsState(initial = AuthState.Idle) when { authState is AuthState.Success -> { // User is signed in MainAppScreen() } else -> { // Show authentication FirebaseAuthScreen(/* ... */) } } } ``` -------------------------------- ### High-Level API Authentication Screen Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Use this composable to create a complete authentication screen with configurable providers and callbacks for sign-in results. It handles common authentication flows and exceptions. ```kotlin FirebaseAuthScreen( configuration = configuration, onSignInSuccess = { result -> val user = result.user val isNewUser = result.additionalUserInfo?.isNewUser ?: false if (isNewUser) { // First-time user navigateToOnboarding() } else { // Returning user navigateToHome() } }, onSignInFailure = { exception -> when (exception) { is AuthException.NetworkException -> { showSnackbar("No internet connection") } is AuthException.TooManyRequestsException -> { showSnackbar("Too many attempts. Please try again later.") } else -> { showSnackbar("Authentication failed: ${exception.message}") } } }, onSignInCancelled = { navigateBack() } ) ``` -------------------------------- ### Update FirebaseUI Auth Provider Configuration Source: https://github.com/firebase/firebaseui-android/blob/master/docs/upgrade-to-10.0.md Shows how to configure authentication providers using the builder pattern in 9.x versus the Kotlin DSL in 10.x. ```java List providers = Arrays.asList( new AuthUI.IdpConfig.EmailBuilder() .setRequireName(true) .build(), new AuthUI.IdpConfig.GoogleBuilder() .build(), new AuthUI.IdpConfig.PhoneBuilder() .build() ); ``` ```kotlin val configuration = authUIConfiguration { providers = listOf( AuthProvider.Email( isDisplayNameRequired = true ), AuthProvider.Google( scopes = listOf("email"), serverClientId = "YOUR_CLIENT_ID" ), AuthProvider.Phone( defaultCountryCode = "US" ) ) } ``` -------------------------------- ### Clean Up Translations Source: https://github.com/firebase/firebaseui-android/blob/master/docs/internal/translations.md Run this script from the project root to clean up translation files after importing. ```shell ./scripts/translations/clean_up_translations.sh ``` -------------------------------- ### Configure FirebaseRecyclerOptions Source: https://github.com/firebase/firebaseui-android/blob/master/database/README.md Build FirebaseRecyclerOptions to configure the adapter with a Firebase query and model class. ```java FirebaseRecyclerOptions options = new FirebaseRecyclerOptions.Builder() .setQuery(query, Chat.class) .build(); ``` -------------------------------- ### Load Image from StorageReference with Glide Source: https://github.com/firebase/firebaseui-android/blob/master/storage/README.md After setting up the AppGlideModule, use GlideApp to load a StorageReference directly into an ImageView. This leverages Glide's caching and performance benefits. ```java // Reference to an image file in Cloud Storage StorageReference storageReference = ...; // ImageView in your Activity ImageView imageView = ...; // Download directly from StorageReference using Glide // (See MyAppGlideModule for Loader registration) GlideApp.with(this /* context */) .load(storageReference) .into(imageView); ``` -------------------------------- ### Configure Email Link Sign-In Source: https://github.com/firebase/firebaseui-android/blob/master/GETTING_STARTED.md Enable email link sign-in and configure the deep link settings. This includes specifying the URL, whether to handle the code in the app, and the Android package name. ```kotlin val configuration = authUIConfiguration { context = applicationContext providers { provider( AuthProvider.Email( isEmailLinkSignInEnabled = true, emailLinkActionCodeSettings = actionCodeSettings { url = "https://example.com/auth" handleCodeInApp = true setAndroidPackageName( "com.example.app", true, null, ) }, ) ) } } ``` -------------------------------- ### Configure FirestoreRecyclerOptions Source: https://github.com/firebase/firebaseui-android/blob/master/firestore/README.md Build FirestoreRecyclerOptions to configure the adapter with a Firestore query and the model class for data conversion. ```java FirestoreRecyclerOptions options = new FirestoreRecyclerOptions.Builder() .setQuery(query, Chat.class) .build(); ``` -------------------------------- ### Generate GPG Key Source: https://github.com/firebase/firebaseui-android/blob/master/docs/internal/releasing.md Steps to generate a new GPG key for signing artifacts. Ensure you choose a strong password and note the Key ID for future use. ```shell gpg --full-generate-key ``` -------------------------------- ### Configure Fade Animations for Auth UI Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Utilize AuthUITransitions with fadeIn and fadeOut for default screen transitions. These are applied if no custom transitions are specified. ```kotlin import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import com.firebase.ui.auth.configuration.AuthUITransitions val configuration = authUIConfiguration { providers { provider(AuthProvider.Phone()) } transitions = AuthUITransitions( enterTransition = { fadeIn() }, exitTransition = { fadeOut() }, popEnterTransition = { fadeIn() }, popExitTransition = { fadeOut() } ) } ``` -------------------------------- ### Create Custom AuthUITheme with Specific Button Shape Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Defines a completely custom theme by instantiating `AuthUITheme` with specific Material Theme components and a desired button shape. This offers maximum control over the UI. ```kotlin val customTheme = AuthUITheme( colorScheme = MaterialTheme.colorScheme, typography = MaterialTheme.typography, shapes = MaterialTheme.shapes, providerButtonShape = RoundedCornerShape(12.dp) ) val configuration = authUIConfiguration { providers { provider(AuthProvider.Google()) provider(AuthProvider.Facebook()) provider(AuthProvider.Email()) } theme = customTheme } ``` -------------------------------- ### Customize Individual Provider Buttons using Default Theme Copy Source: https://github.com/firebase/firebaseui-android/blob/master/auth/README.md Overrides default styles for specific providers (e.g., Google, Facebook) while applying a global shape to all buttons. Use provider IDs like "google.com" for targeting. ```kotlin val customProviderStyles = mapOf( "google.com" to ProviderStyleDefaults.Google.copy( shape = RoundedCornerShape(8.dp), elevation = 4.dp ), "facebook.com" to ProviderStyleDefaults.Facebook.copy( shape = RoundedCornerShape(24.dp), elevation = 0.dp ) ) val customTheme = AuthUITheme.Default.copy( providerButtonShape = RoundedCornerShape(12.dp), // Default for all providerStyles = customProviderStyles // Specific overrides ) val configuration = authUIConfiguration { providers { provider(AuthProvider.Google()) provider(AuthProvider.Facebook()) } theme = customTheme } ``` -------------------------------- ### Run Unit Tests for Specific Module Source: https://github.com/firebase/firebaseui-android/blob/master/CONTRIBUTING.md Run unit tests for a particular module, such as the `auth` module. This is useful for focused testing during development. ```bash ./gradlew :auth:testDebugUnitTest ``` -------------------------------- ### Configure Snapshot Builds Repository Source: https://github.com/firebase/firebaseui-android/blob/master/README.md Add this repository to your build.gradle file to access snapshot versions of FirebaseUI. ```groovy repositories { maven { url "https://oss.jfrog.org/artifactory/oss-snapshot-local" } } ```