Firebase Email & Password Authentication Part 2
Welcome to codingbihar.com. In the last tutorial we have connected firebase with our app and downloaded google-services.json file now this is the second part in which we will add dependency and google-services.json file
How to add dependency?
We can directly add the dependency but it is a little different as we do with older version of android studio.
Lets see how we add in the latest version of Android Studio Iguana
Step1- Go to build.gradle.kts(Module :app)
(A) Add in
plugins {
id("com.google.gms.google-services")
}
(B) Add in
dependencies{
implementation(libs.firebase.auth)
implementation(libs.androidx.navigation.compose)
}
Step 2- Go to libs.versions.toml(Version Catalog) here we add versions and libraries
(A) In the [versions] section add
googleServices = "4.4.1"
firebaseAuth = "22.3.1"
navigationCompose = "2.7.7"
(B) In [libraries] section add the following
google-services = { group = "com.google.gms", name = "google-services", version.ref = "googleServices" }
firebase-auth = { group = "com.google.firebase", name = "firebase-auth", version.ref = "firebaseAuth" }
androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
Another method?
This is the simple method to add dependency
Go to Tools>Firebase>Authentication
Click on Authentication using a custom authentication system
Here as we connected firebase with our app before so we can see app is connected is checked
so just we need to click on Add the Firebase Authentication SDK to your app a pop up window appear click on button "Accept changes"
How to add google-services.gson file?
MainActivity
package com.codingbihar.firebaseproject
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.codingbihar.firebaseproject.ui.theme.FirebaseProjectTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
FirebaseProjectTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
HomeScreen()
}
}
}
}
}
@Composable
fun HomeScreen() {
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = "mainScreen"
) {
composable("mainScreen") {
MainScreen(navController = navController)
}
composable("signUpScreen") {
SignUpScreen(navController)
}
composable("SignInScreen") {
SignInScreen(navController)
}
composable("SuccessfulScreen") {
SuccessfulScreen()
}
composable("ForgotPassword") {
ForgotPasswordScreen()
}
}
}
@Composable
fun MainScreen(navController: NavController) {
Column (Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
){
Text(text = "Firebase Project\nEmail/Password Authentication")
Row (
Modifier
.fillMaxWidth()
.padding(top = 30.dp),
horizontalArrangement = Arrangement.Center){
OutlinedButton(onClick = { navController.navigate("signUpScreen") }) {
Text(text = "SignUp")
}
Spacer(modifier = Modifier.width(100.dp))
OutlinedButton(onClick = { navController.navigate("signInScreen")}) {
Text(text = "SignIn")
}
}
}
}
SignUpScreen
package com.codingbihar.firebaseproject
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import com.google.firebase.auth.FirebaseAuth
@Composable
fun SignUpScreen(navController: NavController) {
var email by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
OutlinedTextField(
value = email,
onValueChange = { email = it },
label = { Text("Email") },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(16.dp))
OutlinedTextField(
value = password,
onValueChange = { password = it },
label = { Text("Password") },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(16.dp))
Button(onClick = {
if (email.isNotEmpty() && password.isNotEmpty()) {
FirebaseAuth.getInstance().createUserWithEmailAndPassword(email, password)
.addOnCompleteListener { task ->
if (task.isSuccessful) {
// Sign-up successful
// You may navigate to another screen or show a confirmation message
println("Sign-up successful")
navController.popBackStack()
} else {
// Handle sign-up failure
println("Sign-up failed: ${task.exception?.message}")
}
}
} else {
// Show error message or toast indicating empty fields
println("Email or password field is empty")
}
}) {
Text("Sign Up")
}
}
}
SignInScreen
package com.codingbihar.firebaseproject
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import com.google.firebase.auth.FirebaseAuth
@Composable
fun SignInScreen(navController: NavController) {
var email by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
val errorMessage = remember { mutableStateOf("") }
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
OutlinedTextField(
value = email,
onValueChange = { email = it },
label = { Text("Email") },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(16.dp))
OutlinedTextField(
value = password,
onValueChange = { password = it },
label = { Text("Password") },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(16.dp))
Button(onClick = {
if (email.isNotEmpty() && password.isNotEmpty()) {
FirebaseAuth.getInstance().signInWithEmailAndPassword(email, password)
.addOnCompleteListener { task ->
if (task.isSuccessful) {
navController.navigate("SuccessfulScreen")
} else {
// Login failed, update error message
println("Login-up unsuccessful")
//errorMessage.value = task.exception?.message ?: "Unknown error"
}
}
} else {
// Show error message for empty email or password
errorMessage.value = "Please fill in all fields"
}
}) {
Text("Login")
}
Spacer(modifier = Modifier.height(8.dp))
TextButton(onClick = { navController.navigate("ForgotPassword") }) {
Text("Forgot Password?")
}
}
}
ForgotPassword
package com.codingbihar.jetpackcredit
import android.widget.Toast
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import com.google.firebase.auth.FirebaseAuth
@Composable
fun ForgotPasswordScreen(navController: NavController) {
var email by remember { mutableStateOf("") }
val context = LocalContext.current
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
OutlinedTextField(
value = email,
onValueChange = { email = it },
label = { Text("Email") },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(16.dp))
Button(onClick = {
if (email.isEmpty()){
Toast.makeText(context,"Email is not filled", Toast.LENGTH_LONG).show()
}
else if (email.isNotEmpty()) FirebaseAuth.getInstance().sendPasswordResetEmail(email)
.addOnCompleteListener { task ->
if (task.isSuccessful) {
// Password reset email sent successfully
// You may navigate to another screen or show a confirmation message
println("Password reset email sent successfully")
navController.popBackStack()
} else {
// Handle password reset email failure
println("Password reset email failed: ${task.exception?.message}")
}
} else {
// Show error message or toast indicating empty email field
println("Email field is empty")
}
}) {
Text("Reset Password")
}
}
}
SuccessfulScreen
package com.codingbihar.firebaseproject
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@Composable
fun SuccessfulScreen() {
Text(text = "Successful Authentication Screen")
}