Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Data Layer에서 ViewModelScope를 사용하지 않도록 변경 #94

Merged
merged 6 commits into from
Dec 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class RunningHistoryLocalDataSourceImpl @Inject constructor(
}

override suspend fun saveRunningHistory(runningHistoryEntity: RunningHistoryEntity): Result<RunningHistory> {
return kotlin.runCatching {
return runCatching {
runningHistoryDao.addRunningHistory(runningHistoryEntity)
runningHistoryEntity.toRunningHistory()
}
Expand Down
16 changes: 16 additions & 0 deletions data/src/main/java/com/whyranoid/data/di/CoroutineModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.whyranoid.data.di

import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import kotlinx.coroutines.Dispatchers

@Module
@InstallIn(SingletonComponent::class)
class CoroutineModule {

@Provides
@IODispatcher
fun provideIODispatcher() = Dispatchers.IO
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.whyranoid.data.di

import javax.inject.Qualifier

@Retention(AnnotationRetention.RUNTIME)
@Qualifier
annotation class IODispatcher
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

annotation class가 뭔가요..

40 changes: 16 additions & 24 deletions data/src/main/java/com/whyranoid/data/group/GroupDataSourceImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.whyranoid.data.group

import com.google.firebase.firestore.FieldValue
import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.ktx.snapshots
import com.whyranoid.data.constant.CollectionId.GROUPS_COLLECTION
import com.whyranoid.data.constant.CollectionId.USERS_COLLECTION
import com.whyranoid.data.constant.FieldId.GROUP_INTRODUCE
Expand All @@ -17,10 +18,9 @@ import com.whyranoid.domain.model.GroupInfo
import com.whyranoid.domain.model.MoGakRunException
import com.whyranoid.domain.model.Rule
import com.whyranoid.domain.model.toRule
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.tasks.await
import java.util.*
Expand Down Expand Up @@ -177,31 +177,23 @@ class GroupDataSourceImpl @Inject constructor(
}

private fun getGroupInfoResponse(groupId: String): Flow<GroupInfoResponse> {
return callbackFlow {
db.collection(GROUPS_COLLECTION)
.document(groupId)
.addSnapshotListener { documentSnapshot, _ ->
trySend(
documentSnapshot?.toObject(GroupInfoResponse::class.java)
?: throw MoGakRunException.FileNotFoundedException
)
}
awaitClose()
}
return db.collection(GROUPS_COLLECTION)
.document(groupId)
.snapshots()
.map { documentSnapshot ->
documentSnapshot.toObject(GroupInfoResponse::class.java)
?: throw MoGakRunException.FileNotFoundedException
}
}

private fun getUserResponse(uid: String): Flow<UserResponse> {
return callbackFlow {
db.collection(USERS_COLLECTION)
.document(uid)
.addSnapshotListener { documentSnapshot, _ ->
trySend(
documentSnapshot?.toObject(UserResponse::class.java)
?: throw MoGakRunException.FileNotFoundedException
)
}
awaitClose()
}
return db.collection(USERS_COLLECTION)
.document(uid)
.snapshots()
.map { documentSnapshot ->
documentSnapshot.toObject(UserResponse::class.java)
?: throw MoGakRunException.FileNotFoundedException
}
}

override suspend fun isDuplicatedGroupName(groupName: String): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import com.whyranoid.domain.model.GroupNotification
import com.whyranoid.domain.model.Rule
import com.whyranoid.domain.model.RunningHistory
import com.whyranoid.domain.repository.GroupRepository
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject

Expand All @@ -21,7 +20,7 @@ class GroupRepositoryImpl @Inject constructor(
return userDataSource.getMyGroupList(uid)
}

override fun getMyGroupListFlow(uid: String, coroutineScope: CoroutineScope) = userDataSource.getMyGroupListFlow(uid, coroutineScope)
override fun getMyGroupListFlow(uid: String) = userDataSource.getMyGroupListFlow(uid)

override suspend fun updateGroupInfo(
groupId: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.whyranoid.data.groupnotification

import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.ktx.snapshots
import com.whyranoid.data.constant.CollectionId.FINISH_NOTIFICATION
import com.whyranoid.data.constant.CollectionId.GROUP_NOTIFICATIONS_COLLECTION
import com.whyranoid.data.constant.CollectionId.RUNNING_HISTORY_COLLECTION
Expand All @@ -12,14 +13,14 @@ import com.whyranoid.domain.model.FinishNotification
import com.whyranoid.domain.model.GroupNotification
import com.whyranoid.domain.model.RunningHistory
import com.whyranoid.domain.model.StartNotification
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.flattenMerge
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.withContext
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.tasks.await
import java.util.UUID
import javax.inject.Inject

Expand All @@ -40,10 +41,10 @@ class GroupNotificationDataSourceImpl @Inject constructor(

private fun getGroupStartNotifications(groupId: String): Flow<List<GroupNotification>> =
callbackFlow {
db.collection(GROUP_NOTIFICATIONS_COLLECTION)
val registration = db.collection(GROUP_NOTIFICATIONS_COLLECTION)
.document(groupId)
.collection(START_NOTIFICATION)
.addSnapshotListener { snapshot, error ->
.addSnapshotListener { snapshot, _ ->
val startNotificationList = mutableListOf<GroupNotification>()
snapshot?.forEach { document ->
val startNotification =
Expand All @@ -53,58 +54,59 @@ class GroupNotificationDataSourceImpl @Inject constructor(
trySend(startNotificationList)
}

awaitClose()
awaitClose {
registration.remove()
}
}

private fun getGroupFinishNotifications(groupId: String): Flow<List<GroupNotification>> =
callbackFlow {
db.collection(GROUP_NOTIFICATIONS_COLLECTION)
.document(groupId)
.collection(FINISH_NOTIFICATION)
.addSnapshotListener { snapshot, error ->
val finishNotificationList = mutableListOf<GroupNotification>()
snapshot?.forEach { document ->
val finishNotificationResponse =
document.toObject(FinishNotificationResponse::class.java)
private fun getGroupFinishNotifications(groupId: String): Flow<List<GroupNotification>> {
return db.collection(GROUP_NOTIFICATIONS_COLLECTION)
.document(groupId)
.collection(FINISH_NOTIFICATION)
.snapshots()
.map { snapshot ->
val finishNotificationList = mutableListOf<GroupNotification>()

finishNotificationResponse.let { finishNotificationResponse ->
db.collection(RUNNING_HISTORY_COLLECTION)
.document(finishNotificationResponse.historyId)
.get()
.addOnSuccessListener {
val runningHistory = it.toObject(RunningHistory::class.java)
snapshot.forEach { document ->
val finishNotificationResponse =
document.toObject(FinishNotificationResponse::class.java)

runningHistory?.let {
finishNotificationList.add(
FinishNotification(
uid = finishNotificationResponse.uid,
runningHistory = runningHistory
)
)
}
trySend(finishNotificationList)
}
finishNotificationResponse.let { finishNotification ->
getRunningHistory(finishNotification.historyId)?.let { runningHistory ->
finishNotificationList.add(
FinishNotification(
uid = finishNotification.uid,
runningHistory = runningHistory
)
)
}
}
}
finishNotificationList
}
}

awaitClose()
}
// TODO : 예외처리
private suspend fun getRunningHistory(historyId: String): RunningHistory? {
return db.collection(RUNNING_HISTORY_COLLECTION)
.document(historyId)
.get()
.await()
.toObject(RunningHistory::class.java)
}

override suspend fun notifyRunningStart(uid: String, groupIdList: List<String>) {
withContext(Dispatchers.IO) {
groupIdList.forEach { groupId ->
db.collection(GROUP_NOTIFICATIONS_COLLECTION)
.document(groupId)
.collection(START_NOTIFICATION)
.document(UUID.randomUUID().toString())
.set(
StartNotification(
startedAt = System.currentTimeMillis(),
uid = uid
)
groupIdList.forEach { groupId ->
db.collection(GROUP_NOTIFICATIONS_COLLECTION)
.document(groupId)
.collection(START_NOTIFICATION)
.document(UUID.randomUUID().toString())
.set(
StartNotification(
startedAt = System.currentTimeMillis(),
uid = uid
)
}
)
}
}

Expand All @@ -113,19 +115,17 @@ class GroupNotificationDataSourceImpl @Inject constructor(
runningHistory: RunningHistory,
groupIdList: List<String>
) {
withContext(Dispatchers.IO) {
groupIdList.forEach { groupId ->
db.collection(GROUP_NOTIFICATIONS_COLLECTION)
.document(groupId)
.collection(FINISH_NOTIFICATION)
.document(UUID.randomUUID().toString())
.set(
FinishNotificationResponse(
uid = uid,
historyId = runningHistory.historyId
)
groupIdList.forEach { groupId ->
db.collection(GROUP_NOTIFICATIONS_COLLECTION)
.document(groupId)
.collection(FINISH_NOTIFICATION)
.document(UUID.randomUUID().toString())
.set(
FinishNotificationResponse(
uid = uid,
historyId = runningHistory.historyId
)
}
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import kotlin.coroutines.resume
class RunnerDataSourceImpl(private val db: FirebaseFirestore) : RunnerDataSource {

override fun getCurrentRunnerCount(): Flow<Int> = callbackFlow {
db.collection(CollectionId.RUNNERS_COLLECTION)
val registration = db.collection(CollectionId.RUNNERS_COLLECTION)
.document(CollectionId.RUNNERS_ID)
.addSnapshotListener { snapshot, _ ->
snapshot?.let {
Expand All @@ -21,7 +21,9 @@ class RunnerDataSourceImpl(private val db: FirebaseFirestore) : RunnerDataSource
}
}

awaitClose()
awaitClose {
registration.remove()
}
}

override suspend fun startRunning(uid: String): Boolean {
Expand Down
3 changes: 1 addition & 2 deletions data/src/main/java/com/whyranoid/data/user/UserDataSource.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package com.whyranoid.data.user

import com.whyranoid.domain.model.GroupInfo
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow

interface UserDataSource {

suspend fun getMyGroupList(uid: String): Result<List<GroupInfo>>

fun getMyGroupListFlow(uid: String, coroutineScope: CoroutineScope): Flow<List<GroupInfo>>
fun getMyGroupListFlow(uid: String): Flow<List<GroupInfo>>
}
23 changes: 15 additions & 8 deletions data/src/main/java/com/whyranoid/data/user/UserDataSourceImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ import com.whyranoid.data.constant.CollectionId.USERS_COLLECTION
import com.whyranoid.data.constant.Exceptions.NO_GROUP_EXCEPTION
import com.whyranoid.data.constant.Exceptions.NO_JOINED_GROUP_EXCEPTION
import com.whyranoid.data.constant.Exceptions.NO_USER_EXCEPTION
import com.whyranoid.data.di.IODispatcher
import com.whyranoid.data.model.GroupInfoResponse
import com.whyranoid.data.model.UserResponse
import com.whyranoid.data.model.toGroupInfo
import com.whyranoid.data.model.toUser
import com.whyranoid.domain.model.GroupInfo
import com.whyranoid.domain.model.User
import com.whyranoid.domain.model.toRule
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
Expand All @@ -22,7 +25,9 @@ import kotlinx.coroutines.tasks.await
import javax.inject.Inject

class UserDataSourceImpl @Inject constructor(
private val db: FirebaseFirestore
private val db: FirebaseFirestore,
@IODispatcher
private val dispatcher: CoroutineDispatcher
) : UserDataSource {

override suspend fun getMyGroupList(uid: String): Result<List<GroupInfo>> {
Expand Down Expand Up @@ -67,27 +72,29 @@ class UserDataSourceImpl @Inject constructor(

// TODO: 예외처리
override fun getMyGroupListFlow(
uid: String,
coroutineScope: CoroutineScope
uid: String
): Flow<List<GroupInfo>> = callbackFlow {
db.collection(USERS_COLLECTION)
val coroutineScope = CoroutineScope(dispatcher)
val registration = db.collection(USERS_COLLECTION)
.document(uid)
.addSnapshotListener { documentSnapshot, _ ->
val myGroupInfoList = mutableListOf<GroupInfo>()
val joinedGroupList =
documentSnapshot?.toObject(UserResponse::class.java)?.joinedGroupList

joinedGroupList?.forEach { groupId ->

coroutineScope.launch {
coroutineScope.launch {
joinedGroupList?.forEach { groupId ->
val groupInfo = getGroupInfo(groupId)
myGroupInfoList.add(groupInfo)
trySend(myGroupInfoList)
}
}
}

awaitClose()
awaitClose {
coroutineScope.cancel()
registration.remove()
}
}

// TODO : 예외 처리
Expand Down
Loading