Skip to content

Commit

Permalink
Merge pull request #111 from YAPP-Github/feature/TNT-187
Browse files Browse the repository at this point in the history
[TNT-187] FCM 기본 세팅
  • Loading branch information
hoyahozz authored Feb 14, 2025
2 parents bd072b0 + 5733dc6 commit fcae642
Show file tree
Hide file tree
Showing 18 changed files with 122 additions and 17 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/android-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ jobs:
echo DEBUG_BASE_API_URL=\"${{ secrets.DEBUG_BASE_API_URL }}\" >> ./local.properties
echo KAKAO_NATIVE_APP_KEY=${{ secrets.KAKAO_NATIVE_APP_KEY }} >> ./local.properties
- name: add google-services.json
run: |
echo '${{ secrets.GOOGLE_SERVICES_JSON }}' > ./app/src/google-services.json
- name: Grant execute permission for gradlew
run: chmod +x gradlew

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,4 @@ fabric.properties
!/gradle/wrapper/gradle-wrapper.jar

# End of https://www.toptal.com/developers/gitignore/api/androidstudio,android
app/google-services.json
5 changes: 5 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ plugins {
id("tnt.android.application")
id("tnt.android.compose")
id("com.google.android.gms.oss-licenses-plugin")
id("com.google.gms.google-services")
}

android {
Expand Down Expand Up @@ -61,4 +62,8 @@ dependencies {
implementation(libs.androidx.activity.compose)
implementation(libs.kakao.user)
implementation(libs.play.services.oss.licenses)

implementation(platform(libs.firebase.bom))
implementation(libs.firebase.messaging)
implementation(libs.firebase.analytics)
}
8 changes: 8 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@
<activity
android:name="com.google.android.gms.oss.licenses.OssLicensesActivity"
android:theme="@style/Theme.AppCompat.NoActionBar" />

<service
android:name=".service.MessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>

</manifest>
19 changes: 19 additions & 0 deletions app/src/main/java/co/kr/tnt/service/MessagingService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package co.kr.tnt.service

import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class MessagingService : FirebaseMessagingService() {

override fun onMessageReceived(message: RemoteMessage) {
super.onMessageReceived(message)
// TODO
}

override fun onNewToken(token: String) {
super.onNewToken(token)
// TODO
}
}
2 changes: 2 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ plugins {
alias(libs.plugins.ksp) apply false
alias(libs.plugins.detekt) apply false
alias(libs.plugins.ktlint)
alias(libs.plugins.google.services) apply false
alias(libs.plugins.firebase.crashlytics) apply false
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ package co.kr.data.network.model
import co.kr.tnt.domain.model.AuthType
import kotlinx.serialization.Serializable

// TODO fcm token
@Serializable
data class LoginRequest(
val socialType: AuthType,
val fcmToken: String = "EMPTY",
val fcmToken: String,
val socialAccessToken: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ internal class LoginRepositoryImpl @Inject constructor(

override suspend fun login(
authType: AuthType,
messagingToken: String,
accessToken: String,
): LoginResult {
val response = loginRemoteDataSource.postLogin(
loginRequest = LoginRequest(
socialType = authType,
fcmToken = messagingToken,
socialAccessToken = accessToken,
),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ interface LoginRepository {

suspend fun login(
authType: AuthType,
messagingToken: String,
accessToken: String,
): LoginResult

Expand Down
3 changes: 3 additions & 0 deletions feature/login/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@ android {

dependencies {
implementation(projects.core.login)

implementation(platform(libs.firebase.bom))
implementation(libs.firebase.messaging)
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ internal class LoginContract {
data class OnCheckTerm(val termState: TermState) : LoginUiEvent
data class OnClickTermLink(val link: String) : LoginUiEvent
data object OnClickNext : LoginUiEvent
data class OnGetMessagingTokenSucceed(val token: String) : LoginUiEvent
}

sealed interface LoginSideEffect : UiSideEffect {
Expand Down
9 changes: 9 additions & 0 deletions feature/login/src/main/java/co/kr/tnt/login/LoginScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
Expand Down Expand Up @@ -54,6 +55,8 @@ import co.kr.tnt.login.LoginContract.LoginUiEvent
import co.kr.tnt.login.LoginContract.LoginUiState
import co.kr.tnt.login.kakao.KakaoLoginSdk
import co.kr.tnt.login.model.TermState
import com.google.firebase.Firebase
import com.google.firebase.messaging.messaging
import kotlinx.coroutines.launch

@OptIn(ExperimentalMaterial3Api::class)
Expand Down Expand Up @@ -139,6 +142,12 @@ internal fun LoginRoute(
}
}
}

SideEffect {
Firebase.messaging.token.addOnCompleteListener {
viewModel.setEvent(LoginUiEvent.OnGetMessagingTokenSucceed(token = it.result ?: ""))
}
}
}

@Composable
Expand Down
3 changes: 3 additions & 0 deletions feature/login/src/main/java/co/kr/tnt/login/LoginViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ internal class LoginViewModel @Inject constructor(
LoginUiState(),
) {
private var loginResult: LoginResult? = null
private var messagingToken: String = ""

override suspend fun handleEvent(event: LoginUiEvent) {
when (event) {
Expand All @@ -39,6 +40,7 @@ internal class LoginViewModel @Inject constructor(
}

LoginUiEvent.OnClickNext -> navigateToSignup()
is LoginUiEvent.OnGetMessagingTokenSucceed -> messagingToken = event.token
}
}

Expand All @@ -51,6 +53,7 @@ internal class LoginViewModel @Inject constructor(
loginRepository.login(
authType = authType,
accessToken = accessToken,
messagingToken = messagingToken,
)
}.onSuccess { loginResult ->
loginResult.userType?.let { userType ->
Expand Down
1 change: 1 addition & 0 deletions feature/main/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ dependencies {
implementation(libs.kotlinx.immutable)
implementation(libs.androidx.core.splashscreen)
implementation(libs.accompanist.permissions)
implementation(libs.firebase.messaging)
androidTestImplementation(libs.hilt.android.testing)
kspAndroidTest(libs.hilt.android.compiler)
}
28 changes: 28 additions & 0 deletions feature/main/src/main/java/co/kr/tnt/main/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package co.kr.tnt.main

import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
Expand All @@ -18,6 +19,7 @@ import co.kr.tnt.main.ui.rememberTnTAppState
import co.kr.tnt.ui.permission.TnTPermission
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.rememberMultiplePermissionsState
import com.google.firebase.messaging.FirebaseMessaging
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject

Expand All @@ -33,6 +35,7 @@ class MainActivity : ComponentActivity() {
super.onCreate(savedInstanceState)
enableEdgeToEdge()

getMessagingToken()
splashScreen.setKeepOnScreenCondition { viewModel.uiState.value.showSplash }

setContent {
Expand All @@ -50,6 +53,16 @@ class MainActivity : ComponentActivity() {
}

CheckPermissionEffect()

LaunchedEffect(viewModel.effect) {
viewModel.effect.collect { effect ->
when (effect) {
is MainContract.MainSideEffect.ShowToast -> {
Toast.makeText(this@MainActivity, effect.message, Toast.LENGTH_SHORT).show()
}
}
}
}
}
}

Expand All @@ -68,4 +81,19 @@ class MainActivity : ComponentActivity() {
}
}
}

// TODO API 변경 시 제거 예정 코드
private fun getMessagingToken() {
FirebaseMessaging
.getInstance()
.token
.addOnSuccessListener { token ->
token?.let {
viewModel.setEvent(MainUiEvent.OnGetMessagingTokenSucceeded(token))
} ?: viewModel.setEvent(MainUiEvent.OnGetMessagingTokenFailed)
}
.addOnFailureListener {
viewModel.setEvent(MainUiEvent.OnGetMessagingTokenFailed)
}
}
}
6 changes: 5 additions & 1 deletion feature/main/src/main/java/co/kr/tnt/main/MainContract.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ internal class MainContract {

sealed class MainUiEvent : UiEvent {
data object OnNotificationPermissionRevoked : MainUiEvent()
data class OnGetMessagingTokenSucceeded(val token: String) : MainUiEvent()
data object OnGetMessagingTokenFailed : MainUiEvent()
}

data object MainSideEffect : UiSideEffect
sealed interface MainSideEffect : UiSideEffect {
data class ShowToast(val message: String) : MainSideEffect
}
}
32 changes: 18 additions & 14 deletions feature/main/src/main/java/co/kr/tnt/main/MainViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,25 @@ internal class MainViewModel @Inject constructor(
private val settingRepository: SettingRepository,
) :
BaseViewModel<MainUiState, MainUiEvent, MainSideEffect>(MainUiState()) {
init {
viewModelScope.launch {
val startDestination = getStartDestination()
override suspend fun handleEvent(event: MainUiEvent) {
when (event) {
MainUiEvent.OnNotificationPermissionRevoked -> settingRepository.setEnablePushNotification(false)
is MainUiEvent.OnGetMessagingTokenSucceeded -> {
viewModelScope.launch {
val startDestination = getStartDestination()

updateState {
copy(
showSplash = false,
startDestination = startDestination,
)
}
}
}

updateState {
copy(
showSplash = false,
startDestination = startDestination,
)
// TODO API 변경 시 제거 예정 코드
MainUiEvent.OnGetMessagingTokenFailed -> {
sendEffect(MainSideEffect.ShowToast("네트워크 환경을 확인하신 후 앱을 재실행해주세요."))
}
}
}
Expand All @@ -47,10 +57,4 @@ internal class MainViewModel @Inject constructor(
},
)
}

override suspend fun handleEvent(event: MainUiEvent) {
when (event) {
MainUiEvent.OnNotificationPermissionRevoked -> settingRepository.setEnablePushNotification(false)
}
}
}
11 changes: 11 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ coroutine = "1.9.0"
hilt = "2.51.1"
hiltNavigationCompose = "1.2.0"

## firebase
googleServices = "4.4.2"
firebaseBom = "33.9.0"
crashlytics = "3.0.3"

## Test
junit = "4.13.2"
junitJupiter = "5.11.4"
Expand Down Expand Up @@ -129,6 +134,10 @@ detekt-plugin = { module = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin", v
ktlint-plugin = { module = "org.jlleitschuh.gradle:ktlint-gradle", version.ref = "ktlint" }
oss-licenses-plugin = { module = "com.google.android.gms:oss-licenses-plugin", version.ref = "ossLicensesPlugin" }

firebase-bom = { module = "com.google.firebase:firebase-bom", version.ref = "firebaseBom" }
firebase-analytics = { module = "com.google.firebase:firebase-analytics" }
firebase-messaging = { module = "com.google.firebase:firebase-messaging" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
Expand All @@ -140,3 +149,5 @@ ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" }
ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" }
google-services = { id = "com.google.gms.google-services", version.ref = "googleServices" }
firebase-crashlytics = { id = "com.google.firebase.crashlytics", version.ref = "crashlytics" }

0 comments on commit fcae642

Please sign in to comment.