diff --git a/app/src/main/java/hu/bme/kszk/szobatarsch/firebase/FireStore.kt b/app/src/main/java/hu/bme/kszk/szobatarsch/firebase/FireStore.kt new file mode 100644 index 0000000000000000000000000000000000000000..fd0f91a59a30b442d0be94e89a6bcfc52d9e0990 --- /dev/null +++ b/app/src/main/java/hu/bme/kszk/szobatarsch/firebase/FireStore.kt @@ -0,0 +1,153 @@ +package hu.bme.kszk.szobatarsch.firebase + +import com.google.firebase.firestore.CollectionReference +import com.google.firebase.firestore.Query +import com.google.firebase.firestore.QuerySnapshot +import com.google.firebase.firestore.ktx.firestore +import com.google.firebase.ktx.Firebase +import hu.bme.kszk.szobatarsch.firebaseUser +import kotlinx.coroutines.cancel +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException +import kotlin.coroutines.suspendCoroutine + +val db get() = Firebase.firestore + +fun <T> getListOfData( + collection: String, + map: suspend (QuerySnapshot) -> List<T>, + queryTransform: (CollectionReference) -> Query = { it }, +): Flow<List<T>> = callbackFlow { + val coll = queryTransform(db.collection(collection)) + val reg = coll.addSnapshotListener { conversations, error -> + if (error != null) { + cancel("Firebase error", error) + return@addSnapshotListener + } + + launch { + val ret = map(conversations!!) + trySend(ret) + } + } + awaitClose { reg.remove() } +} + +val likeableUsers + get(): Flow<List<User>> = getListOfData( + collection = "users", + map = { datas -> + datas.map { data -> + User( + id = data.id, + name = data.get("name") as String, + description = data.get("description") as String, + preferences = data.get("preferences") as Preferences, + dismissedUsers = data.get("dismissedUsers") as List<String>, + likedUsers = data.get("likedUsers") as List<String>, + contacts = data.get("contacts") as String, + ) + } + }, + ) + +val userData + get(): Flow<User> = callbackFlow { + firebaseUser?.let { + val reg = db.collection("users") + .document(it.uid) + .addSnapshotListener { data, error -> + if (error != null) { + cancel("Firebase error", error) + return@addSnapshotListener + } + + launch { + val ret = data?.toObject(User::class.java) + if (ret != null) { + trySend(ret) + } + } + } + awaitClose { reg.remove() } + } + } + +suspend fun getUserById(id: String): User? = suspendCoroutine { continuation -> + db + .collection("users") + .document(id) + .get() + .addOnSuccessListener { + continuation.resume( + it.toObject(User::class.java)?.copy(id = it.id) + ) + } + .addOnFailureListener { + continuation.resumeWithException(it) + } +} + +val matchedUsersData + get(): Flow<List<User>> = getMatchedUsers() + + +private fun getMatchedUsers(): Flow<List<User>> { + var user: User? + runBlocking { + user = getUserById(firebaseUser!!.uid) + } + + return getListOfData( + collection = "users", + map = { datas -> + datas.map { data -> + User( + id = data.id, + name = data.get("name") as String, + description = data.get("description") as String, + preferences = data.get("preferences") as Preferences, + dismissedUsers = data.get("dismissedUsers") as List<String>, + likedUsers = data.get("likedUsers") as List<String>, + contacts = data.get("contacts") as String, + ) + } + }, + queryTransform = { + var q = it.whereArrayContains("likedUsers", firebaseUser!!.uid) + if (user!!.likedUsers.isNotEmpty()) { + q = q.whereIn("id", user!!.likedUsers) + } + q + } + ) +} + +suspend fun registerOrOverwriteUser(user: User): User = suspendCoroutine { continuation -> + db.collection("users") + .document(user.id) + .set(user) + .addOnSuccessListener { + continuation.resume(user) + } + .addOnFailureListener { + continuation.resumeWithException(it) + } +} + +suspend fun updaterUserPrefs(user: User): User = suspendCoroutine { continuation -> + db.collection("users") + .document(user.id) + .update("preferences", user.preferences) + .addOnSuccessListener { + continuation.resume(user) + } + .addOnFailureListener { + continuation.resumeWithException(it) + } +} \ No newline at end of file diff --git a/app/src/main/java/hu/bme/kszk/szobatarsch/firebase/Types.kt b/app/src/main/java/hu/bme/kszk/szobatarsch/firebase/Types.kt new file mode 100644 index 0000000000000000000000000000000000000000..9a434db29379711846291b0383ed00c475b33c81 --- /dev/null +++ b/app/src/main/java/hu/bme/kszk/szobatarsch/firebase/Types.kt @@ -0,0 +1,29 @@ +package hu.bme.kszk.szobatarsch.firebase + +import java.io.Serializable + +data class User( + val id: String = "", + val name: String = "", + val description: String = "", + val preferences: Preferences = Preferences(), + val dismissedUsers: List<String> = listOf(), + val likedUsers: List<String> = listOf(), + val contacts: String = "", +): Serializable + +data class Preferences( + val gender: Int = 0, + val age: Int = 18, + val major: Int = 0, + val semester: Int = 1, + val bedTime: Int = 0, + val wakeUpTime: Int = 0, + val morningShower: Boolean = true, + val eveningShower: Boolean = false, + val frequentNightTimeGuest: Boolean = false, + val frequencyOfCleaning: Int = 0, + val loudness: Int = 0, + val storageSpace: Int = 0, + val ghost: Boolean = false, +): Serializable