Skip to content

Commit

Permalink
firebase auth
Browse files Browse the repository at this point in the history
  • Loading branch information
OmarLkhalil committed Oct 11, 2023
1 parent 9b92a7b commit b986fb7
Show file tree
Hide file tree
Showing 62 changed files with 1,239 additions and 217 deletions.
17 changes: 17 additions & 0 deletions .idea/deploymentTargetDropDown.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ plugins {
alias(libs.plugins.androidApplication)
alias(libs.plugins.kotlinAndroid)
alias(libs.plugins.kotlinKapt)
alias(libs.plugins.firebase)
alias(libs.plugins.hilt)
}

Expand Down Expand Up @@ -75,6 +74,7 @@ dependencies {
implementation(project(mapOf("path" to ":ui:welcome")))
implementation(project(mapOf("path" to ":ui:navigation")))
implementation(project(mapOf("path" to ":common-ui")))
implementation(libs.firebase.firestore.ktx)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.test.ext.junit)
androidTestImplementation(libs.espresso.core)
Expand Down
31 changes: 26 additions & 5 deletions app/src/main/java/com/mobilebreakero/destigo/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,14 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Scaffold
import androidx.compose.ui.Modifier
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.navigation.NavController
import com.google.accompanist.navigation.animation.rememberAnimatedNavController
import com.mobilebreakero.common_ui.viewmodels.AuthViewModel
import com.mobilebreakero.auth.ui.common.components.MainViewModel
import com.mobilebreakero.common_ui.navigation.NavigationRoutes.EMAIL_VERIFICATION_SCREEN
import com.mobilebreakero.common_ui.navigation.NavigationRoutes.HOME_SCREEN
import com.mobilebreakero.common_ui.navigation.NavigationRoutes.START_SCREEN
import com.mobilebreakero.home.components.BottomNavigation
import com.mobilebreakero.destigo.ui.theme.DestiGoTheme
import com.mobilebreakero.navigation.MainNavHost
Expand All @@ -21,10 +27,10 @@ import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class MainActivity : ComponentActivity() {

private val authViewModel by viewModels<AuthViewModel>()

private val FIRST_LAUNCH_PREFS = "FirstLaunchPrefs"
private val FIRST_LAUNCH_KEY = "FirstLaunch"
private val viewModel by viewModels<MainViewModel>()

@OptIn(ExperimentalMaterial3Api::class, ExperimentalAnimationApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
Expand All @@ -46,12 +52,10 @@ class MainActivity : ComponentActivity() {
Box(modifier = Modifier.padding(pv)) {
MainNavHost(
startDestination = isFirstLaunch,

viewModel = authViewModel,
navController
)
AuthState(navController)
}

}
}
}
Expand All @@ -62,4 +66,21 @@ class MainActivity : ComponentActivity() {
editor.apply()
}
}

@Composable
private fun AuthState(
navController: NavController
) {
val isUserSignedOut = viewModel.getAuthState().collectAsState().value
if (isUserSignedOut) {
navController.navigate(START_SCREEN)
} else {
if (viewModel.isEmailVerified) {
navController.navigate(HOME_SCREEN)
} else {
navController.navigate(EMAIL_VERIFICATION_SCREEN)
}
}
}

}
37 changes: 37 additions & 0 deletions app/src/main/java/com/mobilebreakero/destigo/di/AppModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.mobilebreakero.destigo.di

import com.mobilebreakero.domain.repo.AuthRepository
import com.mobilebreakero.domain.usecase.AuthUseCase
import com.mobilebreakero.domain.usecase.CurrentUser
import com.mobilebreakero.domain.usecase.GetAuthState
import com.mobilebreakero.domain.usecase.ReloadUser
import com.mobilebreakero.domain.usecase.SendEmailVerification
import com.mobilebreakero.domain.usecase.SendPasswordResetEmail
import com.mobilebreakero.domain.usecase.SignInWithEmailAndPassword
import com.mobilebreakero.domain.usecase.SignInAnnonymously
import com.mobilebreakero.domain.usecase.SignOut
import com.mobilebreakero.domain.usecase.SignUpWithEmailAndPassword
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent

@Module
@InstallIn(SingletonComponent::class)
object AppModule {

@Provides
fun provideUseCases(
repo: AuthRepository
) = AuthUseCase(
getAuthState = GetAuthState(repo),
signInWithEmailAndPassword = SignInWithEmailAndPassword(repo),
signUpWithEmailAndPassword = SignUpWithEmailAndPassword(repo),
signOut = SignOut(repo),
SignInAnnonymously = SignInAnnonymously(repo),
sendEmailVerification = SendEmailVerification(repo),
sendPasswordResetEmail = SendPasswordResetEmail(repo),
currentUser = CurrentUser(repo),
reloadUser = ReloadUser(repo)
)
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.mobilebreakero.destigo.di

import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.ktx.auth
import com.google.firebase.ktx.Firebase
import com.mobilebreakero.data.repoimpl.AuthRepositoryImpl
import com.mobilebreakero.data.repoimpl.FireStoreRepoImpl
import com.mobilebreakero.domain.repo.AuthRepository
import com.mobilebreakero.domain.repo.FireStoreRepo
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
Expand All @@ -15,13 +15,9 @@ import dagger.hilt.components.SingletonComponent
object FirebaseModule {

@Provides
fun provideFirebaseAuth(): FirebaseAuth = FirebaseAuth.getInstance()
fun provideFirebaseAuth() = Firebase.auth

@Provides
fun providesAuthRepository(impl: AuthRepositoryImpl): AuthRepository = impl
fun providesAuthRepository(auth: FirebaseAuth): AuthRepository = AuthRepositoryImpl(auth)

@Provides
fun provideFireStoreRepo(): FireStoreRepo {
return FireStoreRepoImpl()
}
}
12 changes: 11 additions & 1 deletion common-ui/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ plugins {
alias(libs.plugins.androidlibrary)
alias(libs.plugins.kotlinAndroid)
alias(libs.plugins.kotlinKapt)
alias(libs.plugins.firebase)
alias(libs.plugins.hilt)
}

Expand Down Expand Up @@ -35,6 +34,17 @@ android {
kotlinOptions {
jvmTarget = "17"
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.4.3"
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
}

dependencies {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.mobilebreakero.common_ui.components

class ErrorHandler {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.mobilebreakero.common_ui.components

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.size
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

@Composable
fun LoadingIndicator(){
Column {
Text("Loading...")
CircularProgressIndicator(
modifier = Modifier.size(30.dp),
color = Color.Blue
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.mobilebreakero.common_ui.navigation

import javax.inject.Singleton

@Singleton
object NavigationRoutes {

const val WELCOME_SCREEN = "WelcomeScreen"
const val SIGN_IN_SCREEN = "LoginScreen"
const val SIGN_UP_SCREEN = "SignUpScreen"
const val START_SCREEN = "StartAuthScreen"
const val HOME_SCREEN = "Home"
const val PROFILE_SCREEN = "Profile"
const val INTERESTED_PLACES_SCREEN = "InterestedPlacesScreen"
const val TRIPS_SCREEN = "Trips"
const val SCAN_SCREEN = "Scan"
const val EMAIL_VERIFICATION_SCREEN = "emailVerification"
const val RESET_PASSWORD = "resetPassword"

}
Original file line number Diff line number Diff line change
@@ -1,44 +1,91 @@
package com.mobilebreakero.data.repoimpl


import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.auth.UserProfileChangeRequest
import com.google.firebase.auth.FirebaseAuth.AuthStateListener
import com.mobilebreakero.domain.repo.AuthRepository
import com.mobilebreakero.domain.util.Resource
import com.mobilebreakero.domain.repo.ReloadUserResponse
import com.mobilebreakero.domain.util.Response.Success
import com.mobilebreakero.domain.util.Response.Failure
import com.mobilebreakero.domain.util.await
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.stateIn
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class AuthRepositoryImpl @Inject constructor(
private val firebaseAuth: FirebaseAuth
private val auth: FirebaseAuth
) : AuthRepository {

override val currentUser: FirebaseUser?
get() = firebaseAuth.currentUser
override val currentUser get() = auth.currentUser

override suspend fun sendEmailVerification() = try {
auth.currentUser?.sendEmailVerification()?.await()
Success(true)
} catch (e: Exception) {
Failure(e)
}

override suspend fun login(email: String, password: String): Resource<FirebaseUser> {
override suspend fun reloadFirebaseUser(): ReloadUserResponse {
return try {
val result = firebaseAuth.signInWithEmailAndPassword(email, password).await()
Resource.Success(result.user!!)
auth.currentUser?.reload()?.await()
Success(true)
} catch (e: Exception) {
e.printStackTrace()
Resource.Failure(e)
Failure(e)
}
}

override suspend fun signup(name: String, email: String, password: String): Resource<FirebaseUser> {
return try {
val result = firebaseAuth.createUserWithEmailAndPassword(email, password).await()
result.user?.updateProfile(UserProfileChangeRequest.Builder().setDisplayName(name).build())?.await()
return Resource.Success(result.user!!)
} catch (e: Exception) {
e.printStackTrace()
Resource.Failure(e)
override suspend fun sendPasswordResetEmail(email: String) = try {
auth.sendPasswordResetEmail(email).await()
Success(true)
} catch (e: Exception) {
Failure(e)
}

override fun getAuthState(viewModelScope: CoroutineScope) = callbackFlow {
val authStateListener = AuthStateListener { auth ->
trySend(auth.currentUser == null)
}
auth.addAuthStateListener(authStateListener)
awaitClose {
auth.removeAuthStateListener(authStateListener)
}
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), auth.currentUser == null)

override suspend fun signInAnonymously() = try {
auth.signInAnonymously().await()
Success(true)
} catch (e: Exception) {
Failure(e)
}

override fun logout() {
firebaseAuth.signOut()
override suspend fun signInWithEmailAndPassword(
email: String,
password: String
) = try {
auth.signInWithEmailAndPassword(email, password).await()
Success(true)
} catch (e: Exception) {
Failure(e)
}

override suspend fun signUpWithEmailAndPassword(
email: String,
password: String
) = try {
auth.createUserWithEmailAndPassword(email, password).await()
Success(true)
} catch (e: Exception) {
Failure(e)
}

override suspend fun signOut() = try {
auth.signOut()
Success(true)
} catch (e: Exception) {
Failure(e)
}
}
5 changes: 1 addition & 4 deletions core/domain/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ plugins {
alias(libs.plugins.androidlibrary)
alias(libs.plugins.kotlinAndroid)
alias(libs.plugins.kotlinKapt)
alias(libs.plugins.firebase)
}

android {
Expand Down Expand Up @@ -45,9 +44,7 @@ dependencies {
androidTestImplementation(libs.espresso.core)
implementation(libs.firebase.firestore.ktx)

// firebase
implementation(libs.firebase.bom)
implementation(libs.firebase.product)
implementation(libs.firebase.auth)
implementation(platform("com.google.firebase:firebase-bom:32.3.1"))

}
Loading

0 comments on commit b986fb7

Please sign in to comment.