#44 first try at firebase use-cases
This commit is contained in:
		
							parent
							
								
									27c45842f2
								
							
						
					
					
						commit
						46824f4498
					
				
					 16 changed files with 294 additions and 7 deletions
				
			
		|  | @ -8,6 +8,9 @@ plugins { | ||||||
| 
 | 
 | ||||||
|     // Protobuf |     // Protobuf | ||||||
|     id 'com.google.protobuf' version '0.8.17' |     id 'com.google.protobuf' version '0.8.17' | ||||||
|  | 
 | ||||||
|  |     // Firebase | ||||||
|  |     id 'com.google.gms.google-services' | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| android { | android { | ||||||
|  | @ -108,13 +111,13 @@ dependencies { | ||||||
|     debugImplementation "androidx.compose.ui:ui-tooling:$compose_version" |     debugImplementation "androidx.compose.ui:ui-tooling:$compose_version" | ||||||
| 
 | 
 | ||||||
|     //Firebase |     //Firebase | ||||||
| //    implementation platform('com.google.firebase:firebase-bom:30.4.1') |     implementation platform('com.google.firebase:firebase-bom:31.3.0') | ||||||
| //    implementation 'com.google.firebase:firebase-crashlytics-ktx' |     implementation 'com.google.firebase:firebase-crashlytics-ktx' | ||||||
| //    implementation 'com.google.firebase:firebase-analytics-ktx' |     implementation 'com.google.firebase:firebase-analytics-ktx' | ||||||
| //    implementation 'com.google.firebase:firebase-auth-ktx' |     implementation 'com.google.firebase:firebase-auth-ktx' | ||||||
| //    implementation 'com.google.firebase:firebase-firestore-ktx' |     implementation 'com.google.firebase:firebase-firestore-ktx' | ||||||
| //    implementation 'com.google.firebase:firebase-perf-ktx' |     implementation 'com.google.firebase:firebase-perf-ktx' | ||||||
| //    implementation 'com.google.firebase:firebase-config-ktx' |     implementation 'com.google.firebase:firebase-config-ktx' | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										39
									
								
								app/google-services.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								app/google-services.json
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,39 @@ | ||||||
|  | { | ||||||
|  |   "project_info": { | ||||||
|  |     "project_number": "692936961909", | ||||||
|  |     "project_id": "studeez-1cff2", | ||||||
|  |     "storage_bucket": "studeez-1cff2.appspot.com" | ||||||
|  |   }, | ||||||
|  |   "client": [ | ||||||
|  |     { | ||||||
|  |       "client_info": { | ||||||
|  |         "mobilesdk_app_id": "1:692936961909:android:28a567b1634fc3bdf3ed3c", | ||||||
|  |         "android_client_info": { | ||||||
|  |           "package_name": "be.ugent.sel.studeez" | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "oauth_client": [ | ||||||
|  |         { | ||||||
|  |           "client_id": "692936961909-vdbv9g03mt55uqes4prtbipr6vg8b48j.apps.googleusercontent.com", | ||||||
|  |           "client_type": 3 | ||||||
|  |         } | ||||||
|  |       ], | ||||||
|  |       "api_key": [ | ||||||
|  |         { | ||||||
|  |           "current_key": "AIzaSyCbbg5F_rTrnwUHLDgCWSx4KCECozkvgVE" | ||||||
|  |         } | ||||||
|  |       ], | ||||||
|  |       "services": { | ||||||
|  |         "appinvite_service": { | ||||||
|  |           "other_platform_oauth_client": [ | ||||||
|  |             { | ||||||
|  |               "client_id": "692936961909-vdbv9g03mt55uqes4prtbipr6vg8b48j.apps.googleusercontent.com", | ||||||
|  |               "client_type": 3 | ||||||
|  |             } | ||||||
|  |           ] | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   ], | ||||||
|  |   "configuration_version": "1" | ||||||
|  | } | ||||||
|  | @ -0,0 +1,3 @@ | ||||||
|  | package be.ugent.sel.studeez.data.local.models | ||||||
|  | 
 | ||||||
|  | data class User(val id: String = "", val isAnonymous: Boolean = true) | ||||||
							
								
								
									
										27
									
								
								app/src/main/java/be/ugent/sel/studeez/domain/Performance.kt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								app/src/main/java/be/ugent/sel/studeez/domain/Performance.kt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,27 @@ | ||||||
|  | /* | ||||||
|  | Copyright 2022 Google LLC | ||||||
|  | 
 | ||||||
|  | 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 | ||||||
|  | 
 | ||||||
|  |     https://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. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | package be.ugent.sel.studeez.domain | ||||||
|  | 
 | ||||||
|  | import com.google.firebase.perf.ktx.trace | ||||||
|  | import com.google.firebase.perf.metrics.Trace | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Trace a block with Firebase performance. | ||||||
|  |  * | ||||||
|  |  * Supports both suspend and regular methods. | ||||||
|  |  */ | ||||||
|  | inline fun <T> trace(name: String, block: Trace.() -> T): T = Trace.create(name).trace(block) | ||||||
|  | @ -0,0 +1,34 @@ | ||||||
|  | /* | ||||||
|  | Copyright 2022 Google LLC | ||||||
|  | 
 | ||||||
|  | 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 | ||||||
|  | 
 | ||||||
|  |     https://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. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | package be.ugent.sel.studeez.domain.account | ||||||
|  | 
 | ||||||
|  | import be.ugent.sel.studeez.data.local.models.User | ||||||
|  | import kotlinx.coroutines.flow.Flow | ||||||
|  | 
 | ||||||
|  | interface AccountService { | ||||||
|  |     val currentUserId: String | ||||||
|  |     val hasUser: Boolean | ||||||
|  | 
 | ||||||
|  |     val currentUser: Flow<User> | ||||||
|  | 
 | ||||||
|  |     suspend fun authenticate(email: String, password: String) | ||||||
|  |     suspend fun sendRecoveryEmail(email: String) | ||||||
|  |     suspend fun createAnonymousAccount() | ||||||
|  |     suspend fun linkAccount(email: String, password: String) | ||||||
|  |     suspend fun deleteAccount() | ||||||
|  |     suspend fun signOut() | ||||||
|  | } | ||||||
|  | @ -0,0 +1,84 @@ | ||||||
|  | /* | ||||||
|  | Copyright 2022 Google LLC | ||||||
|  | 
 | ||||||
|  | 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 | ||||||
|  | 
 | ||||||
|  |     https://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. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | package be.ugent.sel.studeez.domain.account | ||||||
|  | 
 | ||||||
|  | import be.ugent.sel.studeez.data.local.models.User | ||||||
|  | import be.ugent.sel.studeez.domain.trace | ||||||
|  | import com.google.firebase.auth.EmailAuthProvider | ||||||
|  | import com.google.firebase.auth.FirebaseAuth | ||||||
|  | import kotlinx.coroutines.channels.awaitClose | ||||||
|  | import kotlinx.coroutines.flow.Flow | ||||||
|  | import kotlinx.coroutines.flow.callbackFlow | ||||||
|  | import kotlinx.coroutines.tasks.await | ||||||
|  | import javax.inject.Inject | ||||||
|  | 
 | ||||||
|  | class AccountServiceImpl @Inject constructor( | ||||||
|  |     private val auth: FirebaseAuth | ||||||
|  | ) : AccountService { | ||||||
|  | 
 | ||||||
|  |     override val currentUserId: String | ||||||
|  |         get() = auth.currentUser?.uid.orEmpty() | ||||||
|  | 
 | ||||||
|  |     override val hasUser: Boolean | ||||||
|  |         get() = auth.currentUser != null | ||||||
|  | 
 | ||||||
|  |     override val currentUser: Flow<User> | ||||||
|  |         get() = callbackFlow { | ||||||
|  |             val listener = | ||||||
|  |                 FirebaseAuth.AuthStateListener { auth -> | ||||||
|  |                     this.trySend(auth.currentUser?.let { User(it.uid, it.isAnonymous) } ?: User()) | ||||||
|  |                 } | ||||||
|  |             auth.addAuthStateListener(listener) | ||||||
|  |             awaitClose { auth.removeAuthStateListener(listener) } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     override suspend fun authenticate(email: String, password: String) { | ||||||
|  |         auth.signInWithEmailAndPassword(email, password).await() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override suspend fun sendRecoveryEmail(email: String) { | ||||||
|  |         auth.sendPasswordResetEmail(email).await() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override suspend fun createAnonymousAccount() { | ||||||
|  |         auth.signInAnonymously().await() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override suspend fun linkAccount(email: String, password: String): Unit = | ||||||
|  |         trace(LINK_ACCOUNT_TRACE) { | ||||||
|  |             val credential = EmailAuthProvider.getCredential(email, password) | ||||||
|  |             auth.currentUser!!.linkWithCredential(credential).await() | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     override suspend fun deleteAccount() { | ||||||
|  |         auth.currentUser!!.delete().await() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override suspend fun signOut() { | ||||||
|  |         if (auth.currentUser!!.isAnonymous) { | ||||||
|  |             auth.currentUser!!.delete() | ||||||
|  |         } | ||||||
|  |         auth.signOut() | ||||||
|  | 
 | ||||||
|  |         // Sign the user back in anonymously. | ||||||
|  |         createAnonymousAccount() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     companion object { | ||||||
|  |         private const val LINK_ACCOUNT_TRACE = "linkAccount" | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,13 @@ | ||||||
|  | package be.ugent.sel.studeez.domain.account | ||||||
|  | 
 | ||||||
|  | import com.google.firebase.auth.FirebaseAuth | ||||||
|  | import kotlinx.coroutines.tasks.await | ||||||
|  | import javax.inject.Inject | ||||||
|  | 
 | ||||||
|  | class AuthenticateUseCase @Inject constructor( | ||||||
|  |     private val auth: FirebaseAuth, | ||||||
|  | ) { | ||||||
|  |     suspend operator fun invoke(email: String, password: String) { | ||||||
|  |         auth.signInWithEmailAndPassword(email, password).await() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,13 @@ | ||||||
|  | package be.ugent.sel.studeez.domain.account | ||||||
|  | 
 | ||||||
|  | import com.google.firebase.auth.FirebaseAuth | ||||||
|  | import kotlinx.coroutines.tasks.await | ||||||
|  | import javax.inject.Inject | ||||||
|  | 
 | ||||||
|  | class CreateAnonymousAccountUseCase @Inject constructor( | ||||||
|  |     private val auth: FirebaseAuth, | ||||||
|  | ) { | ||||||
|  |     suspend operator fun invoke() { | ||||||
|  |         auth.signInAnonymously().await() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,13 @@ | ||||||
|  | package be.ugent.sel.studeez.domain.account | ||||||
|  | 
 | ||||||
|  | import com.google.firebase.auth.FirebaseAuth | ||||||
|  | import kotlinx.coroutines.tasks.await | ||||||
|  | import javax.inject.Inject | ||||||
|  | 
 | ||||||
|  | class DeleteAccountUseCase @Inject constructor( | ||||||
|  |     private val auth: FirebaseAuth, | ||||||
|  | ) { | ||||||
|  |     suspend operator fun invoke() { | ||||||
|  |         auth.currentUser!!.delete().await() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,22 @@ | ||||||
|  | package be.ugent.sel.studeez.domain.account | ||||||
|  | 
 | ||||||
|  | import be.ugent.sel.studeez.domain.trace | ||||||
|  | import com.google.firebase.auth.EmailAuthProvider | ||||||
|  | import com.google.firebase.auth.FirebaseAuth | ||||||
|  | import kotlinx.coroutines.tasks.await | ||||||
|  | import javax.inject.Inject | ||||||
|  | 
 | ||||||
|  | class LinkAccountUseCase @Inject constructor( | ||||||
|  |     private val auth: FirebaseAuth, | ||||||
|  | ) { | ||||||
|  | 
 | ||||||
|  |     suspend operator fun invoke(email: String, password: String): Unit = | ||||||
|  |         trace(LINK_ACCOUNT_TRACE) { | ||||||
|  |             val credential = EmailAuthProvider.getCredential(email, password) | ||||||
|  |             auth.currentUser!!.linkWithCredential(credential).await() | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     companion object { | ||||||
|  |         private const val LINK_ACCOUNT_TRACE = "linkAccount" | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,13 @@ | ||||||
|  | package be.ugent.sel.studeez.domain.account | ||||||
|  | 
 | ||||||
|  | import com.google.firebase.auth.FirebaseAuth | ||||||
|  | import kotlinx.coroutines.tasks.await | ||||||
|  | import javax.inject.Inject | ||||||
|  | 
 | ||||||
|  | class SendRecoveryEmailUseCase @Inject constructor( | ||||||
|  |     private val auth: FirebaseAuth, | ||||||
|  | ) { | ||||||
|  |     suspend operator fun invoke(email: String) { | ||||||
|  |         auth.sendPasswordResetEmail(email).await() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,18 @@ | ||||||
|  | package be.ugent.sel.studeez.domain.account | ||||||
|  | 
 | ||||||
|  | import com.google.firebase.auth.FirebaseAuth | ||||||
|  | import javax.inject.Inject | ||||||
|  | 
 | ||||||
|  | class SignOutUseCase @Inject constructor( | ||||||
|  |     private val auth: FirebaseAuth, | ||||||
|  |     private val createAnonymousAccountUseCase: CreateAnonymousAccountUseCase, | ||||||
|  | ) { | ||||||
|  |     suspend operator fun invoke() { | ||||||
|  |         if (auth.currentUser!!.isAnonymous) { | ||||||
|  |             auth.currentUser!!.delete() | ||||||
|  |         } | ||||||
|  |         auth.signOut() | ||||||
|  | 
 | ||||||
|  |         createAnonymousAccountUseCase() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -6,6 +6,10 @@ buildscript { | ||||||
|         espressoVersion = '3.4.0' |         espressoVersion = '3.4.0' | ||||||
|         kotlinVersion = '1.6.10' |         kotlinVersion = '1.6.10' | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     dependencies { | ||||||
|  |         classpath 'com.google.gms:google-services:4.3.15' | ||||||
|  |     } | ||||||
| }// Top-level build file where you can add configuration options common to all sub-projects/modules. | }// Top-level build file where you can add configuration options common to all sub-projects/modules. | ||||||
| plugins { | plugins { | ||||||
|     id 'com.android.application' version '7.4.2' apply false |     id 'com.android.application' version '7.4.2' apply false | ||||||
|  | @ -15,3 +19,4 @@ plugins { | ||||||
|     // Hilt |     // Hilt | ||||||
|     id 'com.google.dagger.hilt.android' version '2.44' apply false |     id 'com.google.dagger.hilt.android' version '2.44' apply false | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  |  | ||||||
		Reference in a new issue
	
	 reyniersbram
						reyniersbram