#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
|
||||
id 'com.google.protobuf' version '0.8.17'
|
||||
|
||||
// Firebase
|
||||
id 'com.google.gms.google-services'
|
||||
}
|
||||
|
||||
android {
|
||||
|
@ -108,13 +111,13 @@ dependencies {
|
|||
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
|
||||
|
||||
//Firebase
|
||||
// implementation platform('com.google.firebase:firebase-bom:30.4.1')
|
||||
// implementation 'com.google.firebase:firebase-crashlytics-ktx'
|
||||
// implementation 'com.google.firebase:firebase-analytics-ktx'
|
||||
// implementation 'com.google.firebase:firebase-auth-ktx'
|
||||
// implementation 'com.google.firebase:firebase-firestore-ktx'
|
||||
// implementation 'com.google.firebase:firebase-perf-ktx'
|
||||
// implementation 'com.google.firebase:firebase-config-ktx'
|
||||
implementation platform('com.google.firebase:firebase-bom:31.3.0')
|
||||
implementation 'com.google.firebase:firebase-crashlytics-ktx'
|
||||
implementation 'com.google.firebase:firebase-analytics-ktx'
|
||||
implementation 'com.google.firebase:firebase-auth-ktx'
|
||||
implementation 'com.google.firebase:firebase-firestore-ktx'
|
||||
implementation 'com.google.firebase:firebase-perf-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'
|
||||
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.
|
||||
plugins {
|
||||
id 'com.android.application' version '7.4.2' apply false
|
||||
|
@ -15,3 +19,4 @@ plugins {
|
|||
// Hilt
|
||||
id 'com.google.dagger.hilt.android' version '2.44' apply false
|
||||
}
|
||||
|
||||
|
|
Reference in a new issue