May 19, 2022
This is the second in a series of articles dedicated to creating a new Android app from scratch.Jetpack compositorfor the UI and some other tools that Google offers likeFirebase Authentication,Crashlytics,Cloud Fire Tentjdeal with.
Part 1has an overview of what you can do with this app, how it's structured, and what technologies we'll cover in this series. In this second part we will see how the login and registration flows are implemented and howsee model
connects business logic with theFunctions that can be composed🇧🇷 You'll also learn how to add Firebase authentication to your project.
authentication flow
Firebase Authentication
To implement the user authentication flow, we'll use a Firebase product calledauthentication, which lets you securely authenticate users to your application. It supports authentication with passwords, phone numbers, and some popular federated identity providers like Google, Facebook, Twitter, Github, and more.
One of the coolest features of Firebase Authentication isanonymous authentication, which allows you to create an anonymous session for a user without having to ask for any information. Later, it is possible to update an anonymous user account by requiring the user to authenticate with one of the other providers and link their credentials to the existing (anonymous) account.
Start the app for the first time
Nobody likes to create a new account before trying a new app. To give users the best possible experience, we want to let them start using the app without having to sign up first. We'll use anonymous authentication to accomplish this.
Anonymous authentication can be very useful in a situation like this, where we want user data to be protected by security rules from the beginning. Once the application starts, we will start an anonymous session and display thetask screen
, allowing the user to create and edit tasks.
add an account
Once the user has used the app for a while and found they like it, we want to give them the option to upgrade to a full account linked to a login that they can also use on other devices. 🇧🇷 The user can do this by navigating to the settings screen and logging in or creating an account.
On this screen, the user has two options: login or create a new account using the email and password authentication method. At this point, the previously created anonymous account will be associated with these new credentials. This means Firebase will never create a second account for the user.
Depending on the user's authentication status, the configuration screen displays different options. When the logged in user navigates to the settings screen, two new options become available: he can log out alone or delete the account, which will erase all pending items.

Implementation of the authentication flow
Add Firebase to your project
To implement the authentication flow described above, we'll use Firebase authentication. First we need to add the Firebase SDK (Software Development Kit) to the Android project. To do this, we need to add the Make It So Android app to the Make It So Firebase project inFirebase-KonsoleName🇧🇷 Once we're done building the project, we can download a configuration file that we'll add to the project. This configuration file contains all the information the Firebase Android SDK needs to connect to the Firebase project. All these instructions are described in detail in the officialfirebase documentation.
After adding the SDK to the project, we canAdd dependency for Firebase authentication libraryopposite toapp/build.gradle
Opening hours:
dependencies{ // Import BOM to Firebase platformImplementationplatform('com.Google.base of fire:base of fire-born:31,0.0') // Declare dependency on Firebase authentication libraryimplementation 'with.Google.base of fire:base of fire-authentication-ktx'}
Authentication in Compose
Before we talk about using authentication in Compose, let's review how Firebase authentication works with aexercise
🇧🇷 when you look at themDocumentation for Android, you'll find a step-by-step guide showing how to create an instance ofFirebaseAuth
which will later be initialized withembring
Method.
Private Latin I wasauthentication:FirebaseAuthAbort Fun embring() { super.embring()authentication=base of fire.authentication}
In our case, we just use theexercise
to create the first composable function calledMakeItSoApp
. Losexercise
and functions that can be composed should not know anything about the business logic and APIs that thesee models
going to use, that's howMakeItSoActivity
This will look like this:
classMakeItSoActivity: AppCompatActivityAppCompatActivity() { Abort Fun embring(saved instance state:Package?) { super.embring(saved instance state)defineContent{ MakeItSoApp() } }}
this is thatMakeItSoApp
method we see above:
Fun MakeItSoApp() {MakeItSoTheme{ Turn up(cor=MaterialTema.cores.background) { bravuraapplication status= Remember application status() structure( [...]state of structure=application status.state of structure) { [...] } } }}
This is the top-level compositing feature of the app, where we keep a reference to the state of the app so we can monitor changes and recompose screens as needed. Here we also applied the Make It So theme (which defines which colors are used in dark mode and light mode) and added thisstructure
where all screens are displayed.structure
is a composable element that provides slots for many different components and display elements; This is useful for defining the general structure of a screen.
Create the display template
To prevent the composable functions from knowing anything about the business logic, we call the Firebase Authentication API methods ofsee models
🇧🇷 But to do that, we first need to retrieve the data that the user has entered in thetext boxes
of the screens so that we can pass it as a parameter for the authentication methods.
Let's see how this works intela de login
🇧🇷 This screen has quite a bit of data to sync withsee model
(email and passwordstring instruments
🇧🇷 We package this information into aDatenklasse
for ease of handling:
Data class LoginUiState( bravuraE-mail:line= "", bravuraClave:line= "")
inside sideLoginViewModel
let's create onemutable state
according to the state the screen is in:
I wasUI state= mutableStateOf(LoginUiState()) Private Found
onlysee model
You can post new values for itmutable state
. Lostela de login
You can only observe and react to these new states.
@ComponibleFun tela de login(tela pop-up: () ->Unit,see model:LoginViewModel= handleViewModel()) { bravuraUI statethrough thesee model.UI statebasic toolbar(app text.registration information) Share([...]) { email field(UI state.E-mail,see model::onEmailChange,modifier.field modifier()) [...] }}
We can see in the above excerpt that we share themuiState.email
asemail field
composable Let's see what this composable function does:
@ComponibleFun email field(bravura:line,deNuevoValor: (line) ->Unit,modifier:modifier=modifier) { text box with border(single line= real,modifier=modifier,bravura=bravura,onValueChange= { deNuevoValor(That is) },placeholder= { Text(stringResource(app text.E-mail)) },LeaderIcone= { [...] } )}
We initialize theemail field
asbravura
published bysee model
🇧🇷 Every time the user updates this field (by typing something), we send the new value to thedeNuevoValor
Callback passed as a parameter to the composable function.
On themtela de login
that we can compose that we see above, we can see that this callback forwards the email we just wrote to thesee model
(viewModel::onEmailChange
), e assee model
Then post the new email value toUI state
:
Fun onEmailChange(new value:line) {UI state.bravura=UI state.bravura.copy of(E-mail=new value)}
once thesee model
prints the new state, the composite function notices that the state has been updated and automatically updates itself by a process calledredial🇧🇷 Then the new email value will be displayed in the UI (the content in theemail field
will be updated).
Thus, we guarantee that bothsee model
and the function that can be composed always has the most up-to-date informationUI state
, and as soon as the user clicks the login button, thesee model
gets the latest email and password values and passes them as parameters to the service's methods.
Account service creation
The next step is to create theaccount service
, using the service interface and implementation pattern we saw earlier inPart 1of this series It is the sole responsibilitysee model
Invoke service methods based on user interactions with on-screen buttons. We'll use callbacks to get responses from calls made to the Firebase Authentication API. The interface will look like this:
interfaceaccount service{ Fun Create an anonymous account(as a result: (playable?) ->Unit) Fun authenticate(E-mail:line,Clave:line,as a result: (playable?) ->Unit) Fun linkCuenta(E-mail:line,Clave:line,as a result: (playable?) ->Unit)}
We need to implement these methods in theAccountServiceImpl
Class. Here we see another difference from how we used the Authentication API before. Previously, we had to call these methods directly from theexercise
, so we had some context to add for our listeners:
authentication.Login with email and password(E-mail,Clave) .addOnCompleteListener(That is) {assignment-> e (assignment.is successful) { Update UI(authentication.current user) } Most { Update UI(Null) } }
Now, we won't call these methods from theexercise
no more so we won't have themauthentication
instance already initialized and we have no context to attach to the listeners. We can avoid this by using a listener that doesn't need a context. Also note that we canFirebase.auth
Instance in the service implementation without having to initialize it first.
Abort Fun Create an anonymous account(as a result: (playable?) ->Unit) {base of fire.authentication.sign up anonymously() .addOnCompleteListener { as a result(That is.exception) } }Abort Fun authenticate(E-mail:line,Clave:line,as a result: (playable?) ->Unit) {base of fire.authentication.Login with email and password(E-mail,Clave) .addOnCompleteListener { as a result(That is.exception) } }Abort Fun linkCuenta(E-mail:line,Clave:line,as a result: (playable?) ->Unit) { bravuraI WOULD=Email Authentication Provider.get identity(E-mail,Clave)base of fire.authentication.current user!!.linkWithCredential(I WOULD) .addOnCompleteListener { as a result(That is.exception) }}
Now all we have to do is call these methods from thesee models
, with the callback passed as a parameter. Here's an example of thatlinkCuenta
method called byRegistrarseVerModelo
:
account service.linkCuenta(E-mail,Clave) {Mistake-> e (Mistake== Null) { open and unfold(CONFIGURATION SCREEN,SIGN_UP_SCREEN) } Most onError(Mistake)}
This method is called when the user wants to create a new account. we got thoseE-mail
jClave
entered by the user and both passed as parameters to theEmailAuthProvider.getCredential
Method. This method returns the newI WOULDthat we use when callinglinkWithCredential
Firebase-API-Methode.
Combinable display upgrade
Next, let's discuss what happens inside the callback method. After successfully creating the account, we move on to the next step, calling the methodopen and unfold
🇧🇷 This method will reopenconfiguration screen
and turn off the powerregistration screen
from above. As soon as we get back to youconfiguration screen
, aConfigurationUiState
is updated with the new value forIt's an anonymous account
Property.
@ComponibleFun configuration screen(openEnter: () ->Unit,openEnter: () ->Unit,restart the application: () ->Unit,modifier:modifier=modifier,see model:ViewModel Customizations= handleViewModel()) { bravuraUI statethrough thesee model.UI stateShare(modifier=modifier.rellenoMaxWidth() .FillMaxHeight() .Vertical Displacement(recordarScrollState()) ) { [...] e (UI state.It's an anonymous account) { normal map editor(app text.get connected,modifier.Map()) { openEnter() } normal map editor(app text.Create your account here,modifier.Map()) { openEnter() } } Most {exit map{see model.onSignOutClick(restart the application) }RemoveMyAccountCard{see model.onDeleteMyAccountClick(restart the application) } } }}
Since the account we are using is no longer an anonymous account, the composable resource will recompose and update the content displayed to the user and theexit map
it's atRemoveMyAccountCard
instead of login and account creation cards. This way, the UI will reflect the user's authentication status, allowing you to log out or delete your account if you wish.
What is the next
In Part 3 of this series, we'll learn more about Crashlytics and how it can help you improve the quality of your app. We will also see how messages are displayed inSnack bars
and some improvements we can make to avoid duplicate code.
Make it So source code for Android is available atdieses Github-Repository🇧🇷 This article shows how to use callbacks to pass resultsservices
jsee models
, but this pattern is only used in the first version of the Make it So app. Then you must check this out.Tag v1.0.0
if you specifically want to access this code. The latest version usedKotlin-KoroutinenjRio Kotlininstead of callbacks (cf.Part 5 of this seriesUnderstand how this change affects theservices
shown in this article).
If you are also interested in iOS/Mac development, the same app is also available for these platforms. The iOS/Mac version uses SwiftUI to build the UI, which is very similar to building the UI in Compose. The source code can be found atdieses Github-Repository.
If you have any questions, feel free to contact me atblood.
FAQs
How do I add Firebase authentication to my app? ›
To use an authentication provider, you need to enable it in the Firebase console. Go to the Sign-in Method page in the Firebase Authentication section to enable Email/Password sign-in and any other identity providers you want for your app.
How to add Firebase authentication to Android Studio? ›Open the Firebase Assistant: Tools > Firebase. In the Assistant pane, choose a Firebase product to add to your app. Expand its section, then click the tutorial link (for example, Analytics > Log an Analytics event). Click Connect to Firebase to connect your Android project with Firebase.
Is Jetpack Compose better than XML? ›Compose allows you to do more with less code compared to XML. Compose is Intuitive. This means that you just need to tell Compose what you want to show the user. Compose is compatible with all your existing code: you can call Compose code from Views and Views from Compose.
Is Jetpack Compose production ready 2022? ›Find answers to frequently asked questions about Jetpack Compose! What is the current status of Jetpack Compose? Jetpack Compose announced its 1.0 release in July 2021. The API surface is fairly stable and Compose is ready to be used in production.
How do I add two factor authentication to my app? ›- Open your Google Account.
- In the navigation panel, select Security.
- Under “Signing in to Google,” select 2-Step Verification. Get started.
- Follow the on-screen steps.
Yes, you can use Firebase for auth only and link it to your own database. You'll have to use the Firebase Admin SDK in your backend.
How do I use Firebase for OTP authentication? ›- On this page.
- Before you begin. Security concerns.
- Enable Phone Number sign-in for your Firebase project.
- Enable app verification.
- Send a verification code to the user's phone. ...
- Create a PhoneAuthCredential object.
- Sign in the user.
- Test with fictional phone numbers.
- In the Firebase console, open the Auth section.
- On the Sign in method tab, enable the Google sign-in method and click Save.
Click on the </> icon on the front page of your firebase app, and create a client project. Now let's create that dummy user. Head back to Firebase and click 'Continue to console' if you aren't there already. Now on the sidebar, choose 'Authentication', and then in the middle click 'Setup sign-in method'.
How do I link API to Firebase? ›- Navigate to the Realtime Database section of the Firebase console. You'll be prompted to select an existing Firebase project. ...
- Select a starting mode for your Firebase Security Rules: Test mode. ...
- Choose a location for the database. ...
- Click Done.
Where can I import Firebase authentication? ›
Import firebase and firebase/auth
Place a FirebaseAuthProvider component at the top level of your app. ( anywhere as long as it's above the other Auth components ). Then use any of the other components anywhere in your component tree.
- Download the "google-service.json" file from Firebase.
- Go to this address in windows explorer "C:\Users\Your-Username\AndroidStudioProjects" You will see a list of your Android Studio projects.
- Open a desired project, navigate to "app" folder and paste the .json file.
Android supports Gatekeeper for PIN/pattern/password authentication and Fingerprint for fingerprint authentication. Devices that ship with Android 9 and higher can use BiometricPrompt as a single integration point for fingerprint and additional biometrics.
Should i use Jetpack Compose in 2022? ›My advice. If you want to get a job very fast try to learn XML and build some projects with it and if you want to make a good impression to the interviewer you can try to migrate some screens to Jetpack Compose. If you do this you'll learn from both worlds and you'll be able to apply on jobs that require both of them.
Is Jetpack Compose the future? ›Jetpack Compose is Android's recommended modern toolkit for building native UI. It simplifies and accelerates UI development on Android. Quickly bring your app to life with less code, powerful tools, and intuitive Kotlin APIs.
Is Jetpack Compose better than Flutter? ›And as the title suggests I am not comparing these two with Flutter. Jetpack Compose & SwiftUI is much more different than Flutter. Both are for native development and Flutter is for cross-platform. Even though the structure & concept is almost the same still they can't be compared with each other.
Are companies using Jetpack Compose? ›Airbnb. “We've prioritized building sound technical foundations and empowering our engineers to do excellent work. Jetpack Compose enabled both of these goals and is a critical part of our technical strategy.”
Is Jetpack Compose worth learning? ›For the future - yes. To get a job rn - no. Most codebases are still using XML and a lot of people think that compose is not mature enough yet.
Is Android Jetpack Compose stable? ›Since Google announced Jetpack Compose stable 1.0, many companies are getting started to adopt Jetpack Compose into their projects. According to Google's What developers are saying, Jetpack Compose increases their productivity and code quality.
How do you integrate two-factor authentication? ›SMS Token. Perhaps the most common method of implementing 2FA. This method sends the user a unique token via SMS text message, normally a 5-10 digit code, after they have successfully entered their username and password. The user then needs to provide this unique token before they are granted access.
How do you authenticate an app app? ›
- App Opens System Browser. Before starting authentication, the client app presents a system browser, which will handle HTML responses.
- Authorization Request Sent. ...
- Redirect Response Received. ...
- Login Redirect Followed. ...
- User Authenticates. ...
- Login Completes. ...
- Polling Completes. ...
- Authorization Code Returned.
- The app sends a request with the user's credentials to the backend server.
- The server verifies the credentials If the credentials are valid, the server creates a new session along with a random session ID.
- The server sends to the client a response that includes the session ID.
- Step 1: Install the required command line tools. If you haven't already, install the Firebase CLI. ...
- Step 2: Configure your apps to use Firebase. Use the FlutterFire CLI to configure your Flutter apps to connect to Firebase. ...
- Step 3: Initialize Firebase in your app. ...
- Step 4: Add Firebase plugins.
To initialize the Firebase instance in your Expo project, you must create a config object and pass it to the initializeApp() method imported from the firebase/app module. The config object requires an API key and other unique identifiers.
How do I add Firebase events to Google ads? ›- Now, Go to Google Ads and login to the account you link with the Firebase.
- In Google Ads, go to Tools → Measurement → Conversions.
- Click + button.
- Choose App → Google Analytics 4 properties (Firebase) and click continue.
- You can see all of the analytics events that are marked as conversions.
Go to the APIs & auth / APIs section and enable Google Firebase Cloud Messaging for Android. Go to the APIs & auth / Credentials section and click the Create New Key button. Click the Server key button. Impose restrictions (if any), click the Create button.
How do I add flutters to my existing app? ›- Auto-build and import the Flutter module by adding a Flutter SDK hook to your Gradle script.
- Build your Flutter module into a generic Android Archive (AAR) for integration into your own build system and for better Jetifier interoperability with AndroidX.
Create a new Firebase Project
To set up a firebase in flutter, we first have to create a new project in Firebase Console. So, to create a new project. Open Firebase in your browser. Select Firebase Console from the browser's top right corner and sign in using your Gmail Account.
FlutterFire is a set of official plugins that enable you to implement Firebase services in your Flutter app.
How do I authenticate Expo Google with Firebase? ›(Android only) Go to your Firebase project's settings, scroll down to "Your apps" and select your Android app. Under SHA certificate fingerprints , click Add fingerprint , and paste the value of you get for Google Certificate Fingerprint when running expo fetch:android:hashes .
How do I set up Firebase in my project? ›
- In the center of the Firebase console's project overview page, click the Web icon (plat_web) to launch the setup workflow. ...
- Enter your app's nickname. ...
- Click Register app.
- Follow the on-screen instructions to add and initialize the Firebase SDK in your app.
To serve your Express app on Cloud Functions for Firebase, ensure that your Express app (or express-style URL handler) is exported in such a way that Firebase can find it after your library has been npm packed.