Skip to content

Commit

Permalink
[IDLE-500] 다중 디바이스 지원을 위해 FCM Token을 제거할 때 Device Token을 Body에 담도록 변경
Browse files Browse the repository at this point in the history
  • Loading branch information
tgyuuAn committed Nov 5, 2024
1 parent d33c0ca commit c992874
Show file tree
Hide file tree
Showing 10 changed files with 50 additions and 36 deletions.
8 changes: 7 additions & 1 deletion .github/workflows/android_cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ jobs:
- name: Build AAB for Firebase
run: ./gradlew bundleRelease --stacktrace

- name: Upload AAB artifact
uses: actions/upload-artifact@v3
with:
name: app-release.aab
path: app/build/outputs/bundle/release/app-release.aab

- name: Build APK for Testing
run: ./gradlew assembleRelease --stacktrace

Expand All @@ -77,4 +83,4 @@ jobs:
firebase appdistribution:distribute app/build/outputs/apk/release/app-release.apk \
--app ${{ secrets.FIREBASE_APP_ID }} \
--release-notes "~새로운 릴리즈 버전이 날라왔어용~" \
--groups "세얼간이"
--groups "세얼간이"
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ android {
namespace = "com.idle.care"

defaultConfig {
versionCode = 8
versionName = "1.1.1"
versionCode = 9
versionName = "1.1.2"
targetSdk = 34

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import com.idle.network.model.auth.WithdrawalWorkerRequest
import com.idle.network.model.token.TokenResponse
import com.idle.network.source.auth.AuthDataSource
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import javax.inject.Inject
Expand Down Expand Up @@ -116,29 +115,29 @@ class AuthRepositoryImpl @Inject constructor(
)

override suspend fun logoutWorker(): Result<Unit> {
tokenRepository.deleteDeviceToken()
tokenRepository.deleteDeviceToken(getDeviceToken())

return authDataSource.logoutWorker()
.onSuccess { clearUserData() }
}

override suspend fun logoutCenter(): Result<Unit> {
tokenRepository.deleteDeviceToken()
tokenRepository.deleteDeviceToken(getDeviceToken())

return authDataSource.logoutCenter()
.onSuccess { clearUserData() }
}

override suspend fun withdrawalCenter(reason: String, password: String): Result<Unit> {
tokenRepository.deleteDeviceToken()
tokenRepository.deleteDeviceToken(getDeviceToken())

return authDataSource.withdrawalCenter(
WithdrawalCenterRequest(reason = reason, password = password)
).onSuccess { clearUserData() }
}

override suspend fun withdrawalWorker(reason: String): Result<Unit> {
tokenRepository.deleteDeviceToken()
tokenRepository.deleteDeviceToken(getDeviceToken())

return authDataSource.withdrawalWorker(WithdrawalWorkerRequest(reason))
.onSuccess { clearUserData() }
Expand All @@ -163,10 +162,10 @@ class AuthRepositoryImpl @Inject constructor(
) = withContext(Dispatchers.IO) {
launch { tokenDataSource.setRefreshToken(tokenResponse.refreshToken) }
launch { userInfoDataSource.setUserType(userType) }
launch { tokenDataSource.setAccessToken(tokenResponse.accessToken) }
launch { tokenDataSource.setAccessToken(tokenResponse.accessToken) }.join()

val deviceToken = async { getDeviceToken() }
tokenRepository.postDeviceToken(deviceToken.await(), userType = userType)
val deviceToken = getDeviceToken()
tokenRepository.postDeviceToken(deviceToken, userType = userType)
}

private suspend fun clearUserData() = withContext(Dispatchers.IO) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ package com.idle.data.repository.auth

import com.idle.datastore.datasource.TokenDataSource
import com.idle.domain.repositorry.auth.TokenRepository
import com.idle.network.model.auth.FCMTokenRequest
import com.idle.network.model.notification.DeleteFcmTokenRequest
import com.idle.network.model.notification.PostFcmTokenRequest
import com.idle.network.source.notification.NotificationDataSource
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first
Expand All @@ -19,11 +20,12 @@ class TokenRepositoryImpl @Inject constructor(

override suspend fun postDeviceToken(deviceToken: String, userType: String): Result<Unit> =
notificationDataSource.postFCMToken(
FCMTokenRequest(
PostFcmTokenRequest(
deviceToken = deviceToken,
userType = userType,
)
)

override suspend fun deleteDeviceToken(): Result<Unit> = notificationDataSource.deleteFCMToken()
override suspend fun deleteDeviceToken(deviceToken: String): Result<Unit> =
notificationDataSource.deleteFCMToken(DeleteFcmTokenRequest(deviceToken))
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class AuthRepositoryImplTest {
coEvery { userInfoDataSource.clearUserInfo() } just Runs
coEvery { authDataSource.getDeviceToken() } returns "testToken"
coEvery { tokenRepository.postDeviceToken(any(), any()) } returns Result.success(Unit)
coEvery { tokenRepository.deleteDeviceToken() } returns Result.success(Unit)
coEvery { tokenRepository.deleteDeviceToken(any()) } returns Result.success(Unit)
}

@Test
Expand Down Expand Up @@ -109,7 +109,7 @@ class AuthRepositoryImplTest {
// Then
assertTrue(result.isSuccess)
coVerify { tokenDataSource.clearToken() }
coVerify { tokenRepository.deleteDeviceToken() }
coVerify { tokenRepository.deleteDeviceToken(any()) }
coVerify { userInfoDataSource.clearUserType() }
coVerify { userInfoDataSource.clearUserInfo() }
}
Expand All @@ -125,7 +125,7 @@ class AuthRepositoryImplTest {
// Then
assertTrue(result.isSuccess)
coVerify { tokenDataSource.clearToken() }
coVerify { tokenRepository.deleteDeviceToken() }
coVerify { tokenRepository.deleteDeviceToken(any()) }
coVerify { userInfoDataSource.clearUserType() }
coVerify { userInfoDataSource.clearUserInfo() }
}
Expand All @@ -141,7 +141,7 @@ class AuthRepositoryImplTest {
// Then
assertTrue(result.isSuccess)
coVerify { tokenDataSource.clearToken() }
coVerify { tokenRepository.deleteDeviceToken() }
coVerify { tokenRepository.deleteDeviceToken(any()) }
coVerify { userInfoDataSource.clearUserType() }
coVerify { userInfoDataSource.clearUserInfo() }
}
Expand All @@ -157,7 +157,7 @@ class AuthRepositoryImplTest {
// Then
assertTrue(result.isSuccess)
coVerify { tokenDataSource.clearToken() }
coVerify { tokenRepository.deleteDeviceToken() }
coVerify { tokenRepository.deleteDeviceToken(any()) }
coVerify { userInfoDataSource.clearUserType() }
coVerify { userInfoDataSource.clearUserInfo() }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.idle.domain.repositorry.auth

interface TokenRepository {
suspend fun getAccessToken(): String

suspend fun postDeviceToken(deviceToken: String, userType: String): Result<Unit>
suspend fun deleteDeviceToken(): Result<Unit>
suspend fun deleteDeviceToken(deviceToken: String): Result<Unit>
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
package com.idle.network.api

import com.idle.network.model.auth.FCMTokenRequest
import com.idle.network.model.notification.DeleteFcmTokenRequest
import com.idle.network.model.notification.GetMyNotificationResponse
import com.idle.network.model.notification.GetUnreadNotificationCountResponse
import com.idle.network.model.notification.PostFcmTokenRequest
import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.HTTP
import retrofit2.http.PATCH
import retrofit2.http.POST
import retrofit2.http.Path
import retrofit2.http.Query

interface NotificationApi {
@POST("/api/v1/fcm/token")
suspend fun postFCMToken(@Body fcmTokenRequest: FCMTokenRequest): Response<Unit>
suspend fun postFCMToken(@Body postFcmTokenRequest: PostFcmTokenRequest): Response<Unit>

@PATCH("/api/v1/fcm/token")
suspend fun patchFCMToken(@Body fcmTokenRequest: FCMTokenRequest): Response<Unit>

@DELETE("/api/v1/fcm/token")
suspend fun deleteFCMToken(): Response<Unit>
@HTTP(method = "DELETE", path = "/api/v1/fcm/token", hasBody = true)
suspend fun deleteFCMToken(@Body deleteFcmTokenRequest: DeleteFcmTokenRequest): Response<Unit>

@GET("/api/v1/notifications/my")
suspend fun getMyNotifications(
Expand All @@ -33,4 +31,4 @@ interface NotificationApi {

@GET("/api/v1/notifications/count")
suspend fun getUnreadNotificationCount(): Response<GetUnreadNotificationCountResponse>
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.idle.network.model.notification

import kotlinx.serialization.Serializable

@Serializable
data class DeleteFcmTokenRequest(
val deviceToken: String,
)
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.idle.network.model.auth
package com.idle.network.model.notification

import kotlinx.serialization.Serializable

@Serializable
data class FCMTokenRequest(
data class PostFcmTokenRequest(
val deviceToken: String,
val userType: String,
)
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package com.idle.network.source.notification

import com.idle.network.api.NotificationApi
import com.idle.network.model.auth.FCMTokenRequest
import com.idle.network.model.notification.DeleteFcmTokenRequest
import com.idle.network.model.notification.PostFcmTokenRequest
import com.idle.network.model.notification.GetMyNotificationResponse
import com.idle.network.model.notification.GetUnreadNotificationCountResponse
import com.idle.network.util.safeApiCall
Expand All @@ -12,10 +13,11 @@ import javax.inject.Singleton
class NotificationDataSource @Inject constructor(
private val notificationApi: NotificationApi
) {
suspend fun postFCMToken(fcmTokenRequest: FCMTokenRequest): Result<Unit> =
safeApiCall { notificationApi.postFCMToken(fcmTokenRequest) }
suspend fun postFCMToken(postFcmTokenRequest: PostFcmTokenRequest): Result<Unit> =
safeApiCall { notificationApi.postFCMToken(postFcmTokenRequest) }

suspend fun deleteFCMToken(): Result<Unit> = safeApiCall { notificationApi.deleteFCMToken() }
suspend fun deleteFCMToken(deleteFcmTokenRequest: DeleteFcmTokenRequest): Result<Unit> =
safeApiCall { notificationApi.deleteFCMToken(deleteFcmTokenRequest) }

suspend fun getMyNotifications(
next: String?,
Expand Down

0 comments on commit c992874

Please sign in to comment.