Firebase in Android

Abhishek Pathak
7 min readOct 4, 2022

--

Firebase is a service provided by google for various features over online.

Firebase is a platform developed by Google for creating mobile and web applications. It was originally an independent company founded in 2011. In 2014, Google acquired the platform and it is now their flagship offering for app development.

Features provided by Firebase are

Steps to integrate in Android studio

Step 1 : Open firebase console

Step 2: On the Home screen click get started and Add new Project.

Step 3: Add Project name and click on continue

Step 4: Click continue by selecting account type default if project not for business and click on create project. Wait for 1 min’s and the project got ready.

After project got created, it look like below, click continue

Step 5: Below are few features available now you can integrate these features in your android apps.

Step 6: Select Android icon to integrate with your app, after that you can get a screen where you need to put down the details of application like application package name so let’s create an android app inside android studio.

How to add fingerprint in your project ? read this article

Step 7 : Don’t download json file directly click on next and continue to console because I am going to explain the firebase assistant features as well.

Step 8 : Once you reached to app dashboard inside your firebase project. Let’s integrate a feature. I am going to add authentication as my first feature. So click on Build-> Authentication -> Click on Get Started

Step 9: Now you can see here you have few native features like email/phone authentication also you have available options like google, Facebook, twitter etc. I am selecting Email/Password so enable the option by toggle the feature and click on save button.

Step 10 : Next step is to connect android studio with Firebase so Let’s use firebase assistant available inside android studio-> Tools -> Firebase

Step 11: once clicked on Firebase it will show all the features like below

Step 12 : Click on Authentication, Select the option Authenticate using custom for email/password

Step 13 : Click on Firebase to connect, after that a pop up comes up like below, Click on Build

Step 14: Click on Connect button again after build and it will jump you to browser and you can select on project and see like below

Step 15 : Click on connect button and there you go

Step 16 : Now click on Add firebase dependency using firebase after getting a green tick of connected Android studio with Firebase

Step 17 : Click on apply changes and let’s build the android studio

Step 18 : After set up of dependencies successfully, you are good to go for implementation.

Step 19 : Set up a login / registration screen for authentication

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="10dp"
android:background="#F8C4B7"
android:padding="10dp">
<RadioGroup
android:id="@+id/radioGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintBottom_toTopOf="@+id/edtEmail"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<RadioButton
android:id="@+id/loginRadioBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:fontFamily="cursive"
android:text="@string/login"
android:textColor="#6A0A0A"
android:textSize="30sp"
android:textStyle="bold" />
<RadioButton
android:id="@+id/registerRadioBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:checked="true"
android:fontFamily="cursive"
android:text="@string/register"
android:textColor="#073160"
android:textSize="30sp"
android:textStyle="bold" />
</RadioGroup>
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/edtEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="monospace"
android:hint="@string/enter_email"
android:textColor="#130000"
android:textColorHint="#670404"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/edtPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="monospace"
android:hint="@string/enter_password"
android:inputType="textPassword"
android:textColor="#130000"
android:textColorHint="#670404"
android:textSize="18sp"
app:layout_constraintTop_toBottomOf="@+id/edtEmail" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnLogin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="#D61D1D"
android:fontFamily="monospace"
android:hint="@string/enter_email"
android:text="@string/register"
android:textColor="#FFFFFF"
android:textSize="20sp"
app:layout_constraintTop_toBottomOf="@+id/edtPassword" />
<com.google.android.material.progressindicator.CircularProgressIndicator
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/progress"
app:indicatorColor="#16BC4C"
app:trackColor="#B82E2E"
app:trackCornerRadius="100dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

Step 20 : Set up the registration, Login, email verification

class MainActivity : AppCompatActivity(), RadioGroup.OnCheckedChangeListener {
private lateinit var binding: ActivityMainBinding
private lateinit var firebaseAuth: FirebaseAuth
private lateinit var firebaseUser: FirebaseUser
var isLogin = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.radioGroup.setOnCheckedChangeListener(this)
binding.btnLogin.setOnClickListener {
binding.progress.visibility = View.VISIBLE
if (isLogin) {
makeLogin()
} else {
register()
}
}
} private fun register() {
binding.apply {
val email = edtEmail.text.toString()
val password = edtPassword.text.toString()
firebaseAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener { task ->
if (task.isSuccessful) {
Toast.makeText(
this@MainActivity,
"Registered successfully!!",
Toast.LENGTH_SHORT
).show()
if (firebaseAuth.currentUser != null) {
firebaseUser = firebaseAuth.currentUser as FirebaseUser
}
sendEmailVerification()
binding.progress.visibility = View.GONE
} else {
binding.progress.visibility = View.GONE
Toast.makeText(
this@MainActivity,
"Registration got failed!!",
Toast.LENGTH_SHORT
).show()
}
}
}
}
private fun sendEmailVerification() {
firebaseUser.let {
firebaseUser.sendEmailVerification().addOnCompleteListener { task ->
if (task.isSuccessful) {
Toast.makeText(
this@MainActivity,
"Verification email send!!",
Toast.LENGTH_SHORT
).show()
} else {
Toast.makeText(
this@MainActivity,
"Failed to send email for verification",
Toast.LENGTH_SHORT
).show()
}
}
}
}
private fun makeLogin() {
binding.apply {
val email = edtEmail.text.toString()
val password = edtPassword.text.toString()
firebaseAuth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener { task ->
if (task.isSuccessful) {
Toast.makeText(
this@MainActivity,
"Login successfully!!",
Toast.LENGTH_SHORT
).show()
binding.progress.visibility = View.GONE
startActivity(Intent(this@MainActivity, HomeActivity::class.java))
} else {
Toast.makeText(
this@MainActivity,
"Login got failed!!",
Toast.LENGTH_SHORT
).show()
binding.progress.visibility = View.GONE
}
}
}
}
override fun onCheckedChanged(group: RadioGroup, checkId: Int) {
val checkRadioButton = group.findViewById<RadioButton>(group.checkedRadioButtonId)
checkRadioButton?.let {
when (checkRadioButton.id) {
R.id.loginRadioBtn -> {
binding.btnLogin.text = getString(R.string.login)
isLogin = true
}
else -> {
binding.btnLogin.text = getString(R.string.register)
isLogin = false
}
}
}
}
override fun onStart() {
super.onStart()
firebaseAuth = Firebase.auth
if (this::firebaseUser.isInitialized) {
if (firebaseAuth.currentUser != null && firebaseUser != firebaseAuth) {
firebaseUser = firebaseAuth.currentUser as FirebaseUser
}
}
}
}

How to handle Phone Number registration using Jetpack compose?

package com.learning.b38firebasedemo.authentication

import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.viewModels
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.setContent
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import com.google.firebase.FirebaseException
import com.google.firebase.auth.PhoneAuthCredential
import com.google.firebase.auth.PhoneAuthProvider
import com.learning.b38firebasedemo.R
import kotlinx.coroutines.launch
import java.util.concurrent.TimeUnit

class PhoneRegisterActivity : ComponentActivity() {
private val viewModel: PhoneRegisterViewModel by viewModels()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
PhoneRegisterScreen(viewModel)
}
}
}

@Composable
fun PhoneRegisterScreen(viewModel: PhoneRegisterViewModel) {
var number by remember { mutableStateOf("") }
var isOTPGenerated by remember { mutableStateOf(false) }
val scaffoldState = rememberScaffoldState()

Scaffold(
scaffoldState = scaffoldState,
content = {
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
OutlinedTextField(
value = number,
onValueChange = { number = it },
label = { Text(text = "Mobile Number") },
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Number)
)

Spacer(modifier = Modifier.height(16.dp))

Button(
onClick = {
if (!isOTPGenerated) {
viewModel.sendOTP(number)
isOTPGenerated = true
} else {
viewModel.verifyOTP(number)
}
}
) {
Text(text = if (isOTPGenerated) "Verify OTP" else "Send OTP")
}
}
}
)

LaunchedEffect(viewModel.events) {
viewModel.events.collect { event ->
when (event) {
is PhoneRegisterViewModel.Event.Success -> {
if (event.message.isNotEmpty()) {
scaffoldState.snackbarHostState.showSnackbar(event.message)
}
if (event.navigateToHome) {
// Navigate to HomeActivity
// startActivity(Intent(this, HomeActivity::class.java))
}
}
is PhoneRegisterViewModel.Event.Error -> {
if (event.message.isNotEmpty()) {
scaffoldState.snackbarHostState.showSnackbar(event.message)
}
}
}
}
}
}

@Composable
fun PhoneRegisterViewModel(
sendOTP: (String) -> Unit,
verifyOTP: (String) -> Unit
) {
val scope = rememberCoroutineScope()

val events = produceState(initialValue = PhoneRegisterViewModel.Event()) {
callback = object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
override fun onVerificationCompleted(p0: PhoneAuthCredential) {
value = state.value.copy(message = "Verification Completed")
}

override fun onVerificationFailed(p0: FirebaseException) {
value = state.value.copy(message = "Verification Failed")
}

override fun onCodeSent(
verificationId: String,
token: PhoneAuthProvider.ForceResendingToken
) {
value = state.value.copy(
message = "Code Sent",
verificationId = verificationId,
resentToken = token
)
}
}
}

fun sendOTP(number: String) {
// Call Firebase to send OTP
// Handle the verification state changes in the callback
// ...
}

fun verifyOTP(otp: String) {
val credential = PhoneAuthProvider.getCredential(
events.value.verificationId,
otp
)
// Call Firebase to verify OTP
// Handle the verification result
// ...
}

DisposableEffect(key1 = events) {
onDispose {
// Clean up resources if needed
}
}
}

data class Event(
val message: String = "",
val verificationId: String = "",
val resentToken: PhoneAuthProvider.ForceResendingToken = PhoneAuthProvider.ForceResendingToken.INVALID_TOKEN,
val navigateToHome: Boolean = false
)

You can get the full source code of chatting app from my github repo

Thanks for reading this article. Be sure to click 👏 below to applause this article if you found it helpful. It means a lot to me.

--

--