diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index d1ab406f..76f37af5 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -4,10 +4,12 @@ plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.serialization)
+ alias(libs.plugins.kotlin.compose)
alias(libs.plugins.dagger.hilt)
id("org.jetbrains.kotlin.kapt")
alias(libs.plugins.navigationSafeArgs)
- id("com.google.gms.google-services")
+ alias(libs.plugins.googleServices)
+ alias(libs.plugins.firebaseCrashlytics)
}
val properties = Properties().apply {
@@ -77,7 +79,6 @@ android {
kotlinOptions {
jvmTarget = "11"
}
- composeOptions { kotlinCompilerExtensionVersion = "1.5.14" }
}
dependencies {
@@ -163,7 +164,8 @@ dependencies {
implementation(libs.accompanist.permissions)
// Firebase
- implementation(platform("com.google.firebase:firebase-bom:33.4.0"))
- implementation("com.google.firebase:firebase-analytics-ktx")
- implementation("com.google.firebase:firebase-config-ktx")
+ implementation(platform(libs.firebase.bom))
+ implementation(libs.firebase.analytics.ktx)
+ implementation(libs.firebase.config.ktx)
+ implementation(libs.firebase.crashlytics)
}
\ No newline at end of file
diff --git a/app/src/main/java/com/kuit/findu/analytics/AnalyticsEvent.kt b/app/src/main/java/com/kuit/findu/analytics/AnalyticsEvent.kt
new file mode 100644
index 00000000..bd63666a
--- /dev/null
+++ b/app/src/main/java/com/kuit/findu/analytics/AnalyticsEvent.kt
@@ -0,0 +1,16 @@
+package com.kuit.findu.analytics
+
+data class AnalyticsEvent(
+ val type: String,
+ val extras: List = emptyList(),
+) {
+ data class Param(
+ val key: String,
+ val value: String,
+ )
+
+ companion object {
+ const val SCREEN_VIEW = "screen_view" // TYPE
+ const val SCREEN_NAME = "screen_name" // EXTRA_KEY
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/kuit/findu/analytics/AnalyticsExt.kt b/app/src/main/java/com/kuit/findu/analytics/AnalyticsExt.kt
new file mode 100644
index 00000000..5c03728f
--- /dev/null
+++ b/app/src/main/java/com/kuit/findu/analytics/AnalyticsExt.kt
@@ -0,0 +1,36 @@
+package com.kuit.findu.analytics
+
+fun AnalyticsHelper.logScreenView(screenName: String) {
+ logEvent(
+ AnalyticsEvent(
+ type = AnalyticsEvent.SCREEN_VIEW,
+ extras = listOf(
+ AnalyticsEvent.Param(AnalyticsEvent.SCREEN_NAME, screenName),
+ ),
+ ),
+ )
+}
+
+fun AnalyticsHelper.logUserSignIn(userName: String, type: String) {
+ logEvent(
+ AnalyticsEvent(
+ type = "signed_in",
+ extras = listOf(
+ AnalyticsEvent.Param("user_name", userName),
+ AnalyticsEvent.Param("login_type", type),
+ ),
+ ),
+ )
+}
+
+fun AnalyticsHelper.logUserSignUp(userName: String) {
+ logEvent(
+ AnalyticsEvent(
+ type = "signed_in",
+ extras = listOf(
+ AnalyticsEvent.Param("user_name", userName),
+ AnalyticsEvent.Param("login_type", "Kakao"),
+ ),
+ ),
+ )
+}
diff --git a/app/src/main/java/com/kuit/findu/analytics/AnalyticsHelper.kt b/app/src/main/java/com/kuit/findu/analytics/AnalyticsHelper.kt
new file mode 100644
index 00000000..69716ff2
--- /dev/null
+++ b/app/src/main/java/com/kuit/findu/analytics/AnalyticsHelper.kt
@@ -0,0 +1,5 @@
+package com.kuit.findu.analytics
+
+interface AnalyticsHelper {
+ fun logEvent(event: AnalyticsEvent)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/kuit/findu/analytics/AnalyticsHelperImpl.kt b/app/src/main/java/com/kuit/findu/analytics/AnalyticsHelperImpl.kt
new file mode 100644
index 00000000..f79af806
--- /dev/null
+++ b/app/src/main/java/com/kuit/findu/analytics/AnalyticsHelperImpl.kt
@@ -0,0 +1,21 @@
+package com.kuit.findu.analytics
+
+import com.google.firebase.analytics.FirebaseAnalytics
+import com.google.firebase.analytics.logEvent
+import javax.inject.Inject
+
+class AnalyticsHelperImpl @Inject constructor(
+ private val firebaseAnalytics: FirebaseAnalytics,
+) : AnalyticsHelper {
+ override fun logEvent(event: AnalyticsEvent) {
+ firebaseAnalytics.logEvent(event.type) {
+ for (extra in event.extras) {
+ // Key, Value Max Length에 따른 slicing
+ param(
+ key = extra.key.take(40),
+ value = extra.value.take(100),
+ )
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/kuit/findu/analytics/di/FirebaseModule.kt b/app/src/main/java/com/kuit/findu/analytics/di/FirebaseModule.kt
new file mode 100644
index 00000000..30fa006d
--- /dev/null
+++ b/app/src/main/java/com/kuit/findu/analytics/di/FirebaseModule.kt
@@ -0,0 +1,37 @@
+package com.kuit.findu.analytics.di
+
+import com.google.firebase.Firebase
+import com.google.firebase.analytics.FirebaseAnalytics
+import com.google.firebase.analytics.analytics
+import com.google.firebase.crashlytics.FirebaseCrashlytics
+import com.google.firebase.crashlytics.crashlytics
+import com.kuit.findu.analytics.AnalyticsHelper
+import com.kuit.findu.analytics.AnalyticsHelperImpl
+import dagger.Binds
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import javax.inject.Singleton
+
+@Module
+@InstallIn(SingletonComponent::class)
+abstract class FirebaseModule {
+ @Binds
+ @Singleton
+ abstract fun bindsAnalyticsHelper(analyticsHelperImpl: AnalyticsHelperImpl): AnalyticsHelper
+
+ companion object {
+ @Provides
+ @Singleton
+ fun provideFirebaseAnalytics(): FirebaseAnalytics {
+ return Firebase.analytics
+ }
+
+ @Provides
+ @Singleton
+ fun provideFirebaseCrashlytics(): FirebaseCrashlytics {
+ return Firebase.crashlytics
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/kuit/findu/data/dataremote/util/ErrorTrackingInterceptor.kt b/app/src/main/java/com/kuit/findu/data/dataremote/util/ErrorTrackingInterceptor.kt
new file mode 100644
index 00000000..8550122f
--- /dev/null
+++ b/app/src/main/java/com/kuit/findu/data/dataremote/util/ErrorTrackingInterceptor.kt
@@ -0,0 +1,45 @@
+package com.kuit.findu.data.dataremote.util
+
+import com.google.firebase.crashlytics.FirebaseCrashlytics
+import com.google.firebase.crashlytics.recordException
+import okhttp3.Interceptor
+import okhttp3.Response
+import javax.inject.Inject
+
+class ErrorTrackingInterceptor @Inject constructor(
+ private val firebaseCrashlytics: FirebaseCrashlytics,
+) : Interceptor {
+ override fun intercept(chain: Interceptor.Chain): Response {
+ val request = chain.request()
+ val response: Response
+
+ try {
+ response = chain.proceed(request)
+ } catch (e: Exception) {
+ // 1. 네트워크 자체가 끊긴 경우 등 (IOException)
+ firebaseCrashlytics.recordException(e)
+ throw e
+ }
+
+ // 2. 서버에서 응답은 왔으나 4xx, 5xx 에러인 경우
+ if (!response.isSuccessful) {
+ val code = response.code
+
+ val url = request.url.toString()
+
+ // Crashlytics에 상세 정보 기록
+ val exceptionMessage = when (response.code) {
+ in (400..499) -> "Client $code Error"
+ in (500..599) -> "Server $code Error"
+ else -> "Unknown $code Error"
+ }
+ firebaseCrashlytics.recordException(Exception(exceptionMessage)) {
+ key("api_method", request.method)
+ key("api_url", url)
+ key("api_status", code)
+ }
+ }
+
+ return response
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/kuit/findu/di/NetworkModule.kt b/app/src/main/java/com/kuit/findu/di/NetworkModule.kt
index 76021961..034b54f6 100644
--- a/app/src/main/java/com/kuit/findu/di/NetworkModule.kt
+++ b/app/src/main/java/com/kuit/findu/di/NetworkModule.kt
@@ -1,11 +1,13 @@
package com.kuit.findu.di
import android.content.Context
+import com.google.firebase.crashlytics.FirebaseCrashlytics
+import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import com.kuit.findu.BuildConfig
import com.kuit.findu.BuildConfig.DEBUG
import com.kuit.findu.data.datalocal.datasource.TokenLocalDataSource
import com.kuit.findu.data.dataremote.util.AuthInterceptor
-import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
+import com.kuit.findu.data.dataremote.util.ErrorTrackingInterceptor
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@@ -39,13 +41,15 @@ object NetworkModule {
@Singleton
fun providesOkHttpClient(
loggingInterceptor: HttpLoggingInterceptor,
- authInterceptor: AuthInterceptor
+ authInterceptor: AuthInterceptor,
+ errorTrackingInterceptor: ErrorTrackingInterceptor,
): OkHttpClient =
OkHttpClient.Builder().apply {
connectTimeout(10, TimeUnit.SECONDS)
writeTimeout(10, TimeUnit.SECONDS)
readTimeout(10, TimeUnit.SECONDS)
if (DEBUG) addInterceptor(loggingInterceptor)
+ else addInterceptor(errorTrackingInterceptor)
addInterceptor(authInterceptor)
}.build()
@@ -60,17 +64,25 @@ object NetworkModule {
@Singleton
fun provideAuthInterceptor(
tokenLocalDataSource: TokenLocalDataSource,
- @ApplicationContext context: Context
+ @ApplicationContext context: Context,
): AuthInterceptor {
return AuthInterceptor(tokenLocalDataSource, context)
}
+ @Provides
+ @Singleton
+ fun provideErrorTrackingInterceptor(
+ firebaseCrashlytics: FirebaseCrashlytics,
+ ): ErrorTrackingInterceptor {
+ return ErrorTrackingInterceptor(firebaseCrashlytics)
+ }
+
@ExperimentalSerializationApi
@Provides
@Singleton
fun providesRetrofit(
okHttpClient: OkHttpClient,
- json: Json
+ json: Json,
): Retrofit =
Retrofit.Builder()
.baseUrl(BuildConfig.BASE_URL)
diff --git a/app/src/main/java/com/kuit/findu/presentation/ui/home/HomeFragment.kt b/app/src/main/java/com/kuit/findu/presentation/ui/home/HomeFragment.kt
index 93661b62..a5f2d68a 100644
--- a/app/src/main/java/com/kuit/findu/presentation/ui/home/HomeFragment.kt
+++ b/app/src/main/java/com/kuit/findu/presentation/ui/home/HomeFragment.kt
@@ -36,7 +36,7 @@ class HomeFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
- savedInstanceState: Bundle?
+ savedInstanceState: Bundle?,
): View {
_binding = FragmentHomeBinding.inflate(inflater, container, false)
return binding.root
@@ -76,11 +76,22 @@ class HomeFragment : Fragment() {
}
is HomeUiEffect.ShowToast -> {
- Toast.makeText(requireContext(), sideEffect.message, Toast.LENGTH_SHORT).show()
+ Toast.makeText(
+ requireContext(),
+ sideEffect.message,
+ Toast.LENGTH_SHORT
+ ).show()
}
- is HomeUiEffect.NavigateToProtectList -> TODO()
- is HomeUiEffect.NavigateToReportList -> TODO()
+ is HomeUiEffect.NavigateToProtectList -> {}
+ is HomeUiEffect.NavigateToReportList -> {}
+
+ is HomeUiEffect.NavigateToFindReport -> {
+ navigateToFindReport()
+ }
+ is HomeUiEffect.NavigateToLostReport -> {
+ navigateToLostReport()
+ }
is HomeUiEffect.Dial -> call120()
}
@@ -110,7 +121,11 @@ class HomeFragment : Fragment() {
homeViewModel.handleEvent(HomeUiEvent.OnAlarmButtonClick)
},
onIndicatorSelected = { reportDurationType ->
- homeViewModel.handleEvent(HomeUiEvent.OnHomeReportDurationClick(reportDurationType))
+ homeViewModel.handleEvent(
+ HomeUiEvent.OnHomeReportDurationClick(
+ reportDurationType
+ )
+ )
},
userNickname = uiState.nickname,
navigateToProtectDetail = { protectAnimal ->
@@ -128,13 +143,18 @@ class HomeFragment : Fragment() {
onReportDialogDismiss = {
homeViewModel.handleEvent(HomeUiEvent.OnReportDialogDismiss)
},
- onLostReportClick = {},
- onFindReportClick = {},
+ onLostReportClick = {
+ homeViewModel.navigateToLostReport()
+ },
+ onFindReportClick = {
+ homeViewModel.navigateToFindReport()
+ },
onPhoneClicked = {
homeViewModel.dial()
},
- navigateToHomeExtra = { homeExtraButtonType->
- navigateToHomeExtra(homeExtraButtonType) },
+ navigateToHomeExtra = { homeExtraButtonType ->
+ navigateToHomeExtra(homeExtraButtonType)
+ },
)
}
@@ -192,6 +212,18 @@ class HomeFragment : Fragment() {
}
}
+ private fun navigateToLostReport() {
+ findNavController().navigate(
+ HomeFragmentDirections.actionFragmentHomeToFragmentMissingReport()
+ )
+ }
+
+ private fun navigateToFindReport() {
+ findNavController().navigate(
+ HomeFragmentDirections.actionFragmentHomeToFragmentWitnessReport()
+ )
+ }
+
private fun openWebLink(url: String) {
val intent = Intent(Intent.ACTION_VIEW, url.toUri())
requireActivity().startActivity(intent)
diff --git a/app/src/main/java/com/kuit/findu/presentation/ui/home/viewmodel/HomeViewModel.kt b/app/src/main/java/com/kuit/findu/presentation/ui/home/viewmodel/HomeViewModel.kt
index 2b74cffe..47c5f3c9 100644
--- a/app/src/main/java/com/kuit/findu/presentation/ui/home/viewmodel/HomeViewModel.kt
+++ b/app/src/main/java/com/kuit/findu/presentation/ui/home/viewmodel/HomeViewModel.kt
@@ -32,12 +32,16 @@ data class HomeUiState(
val bannerCurrentPage: Int = 0,
val isScrollToTopVisible: Boolean = false,
val isReportDialogVisible: Boolean = false,
- val locationPermission: Boolean = false
+ val locationPermission: Boolean = false,
) {
val userHomeUserStatusType: HomeUserStatusType
get() = when {
!locationPermission -> HomeUserStatusType.LOCATION_DENIED
- nickname.isEmpty() || nickname.equals(GUEST_NAME, ignoreCase = false) -> HomeUserStatusType.GUEST
+ nickname.isEmpty() || nickname.equals(
+ GUEST_NAME,
+ ignoreCase = false
+ ) -> HomeUserStatusType.GUEST
+
else -> HomeUserStatusType.MEMBER
}
}
@@ -68,6 +72,8 @@ sealed class HomeUiEffect {
data object NavigateToReportList : HomeUiEffect()
data class NavigateToProtectDetail(val animal: ProtectAnimal) : HomeUiEffect()
data class NavigateToReportDetail(val animal: ReportAnimal) : HomeUiEffect()
+ data object NavigateToLostReport : HomeUiEffect()
+ data object NavigateToFindReport : HomeUiEffect()
data class OpenWebLink(val url: String) : HomeUiEffect()
data class ShowToast(val message: String) : HomeUiEffect()
@@ -77,7 +83,7 @@ sealed class HomeUiEffect {
@HiltViewModel
class HomeViewModel @Inject constructor(
private val homeUseCase: GetHomeUseCase,
- private val getNicknameUseCase: GetNicknameUseCase
+ private val getNicknameUseCase: GetNicknameUseCase,
) : ViewModel() {
private val _uiState = MutableStateFlow(HomeUiState())
@@ -125,17 +131,21 @@ class HomeViewModel @Inject constructor(
_uiState.update { it.copy(loadState = LoadState.Loading) }
homeUseCase().fold(
onSuccess = { data ->
- _uiState.update { it.copy(
- loadState = LoadState.Success,
- homeData = data,
- errorMessage = null
- ) }
+ _uiState.update {
+ it.copy(
+ loadState = LoadState.Success,
+ homeData = data,
+ errorMessage = null
+ )
+ }
},
onFailure = { error ->
- _uiState.update { it.copy(
- loadState = LoadState.Error,
- errorMessage = error.message ?: "데이터를 불러오는 중 오류가 발생했습니다."
- ) }
+ _uiState.update {
+ it.copy(
+ loadState = LoadState.Error,
+ errorMessage = error.message ?: "데이터를 불러오는 중 오류가 발생했습니다."
+ )
+ }
}
)
}
@@ -154,29 +164,35 @@ class HomeViewModel @Inject constructor(
homeUseCase().fold(
onSuccess = { data ->
- _uiState.update { it.copy(
- loadState = LoadState.Success,
- homeData = data,
- errorMessage = null,
- isRefreshing = false
- ) }
+ _uiState.update {
+ it.copy(
+ loadState = LoadState.Success,
+ homeData = data,
+ errorMessage = null,
+ isRefreshing = false
+ )
+ }
},
onFailure = { error ->
- _uiState.update { it.copy(
- loadState = LoadState.Error,
- errorMessage = error.message ?: "데이터를 새로고침하는 중 오류가 발생했습니다.",
- isRefreshing = false
- ) }
+ _uiState.update {
+ it.copy(
+ loadState = LoadState.Error,
+ errorMessage = error.message ?: "데이터를 새로고침하는 중 오류가 발생했습니다.",
+ isRefreshing = false
+ )
+ }
}
)
}
}
private fun clearError() {
- _uiState.update { it.copy(
- errorMessage = null,
- loadState = if (_uiState.value.homeData != null) LoadState.Success else LoadState.Idle
- ) }
+ _uiState.update {
+ it.copy(
+ errorMessage = null,
+ loadState = if (_uiState.value.homeData != null) LoadState.Success else LoadState.Idle
+ )
+ }
}
@@ -215,6 +231,17 @@ class HomeViewModel @Inject constructor(
}
}
+ fun navigateToLostReport() {
+ viewModelScope.launch {
+ _uiEffect.send(HomeUiEffect.NavigateToLostReport)
+ }
+ }
+
+ fun navigateToFindReport() {
+ viewModelScope.launch {
+ _uiEffect.send(HomeUiEffect.NavigateToFindReport)
+ }
+ }
fun dial() {
viewModelScope.launch {
diff --git a/app/src/main/java/com/kuit/findu/presentation/ui/login/viewmodel/LoginViewModel.kt b/app/src/main/java/com/kuit/findu/presentation/ui/login/viewmodel/LoginViewModel.kt
index b7f70f43..8480dd4d 100644
--- a/app/src/main/java/com/kuit/findu/presentation/ui/login/viewmodel/LoginViewModel.kt
+++ b/app/src/main/java/com/kuit/findu/presentation/ui/login/viewmodel/LoginViewModel.kt
@@ -3,6 +3,8 @@ package com.kuit.findu.presentation.ui.login.viewmodel
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import com.kuit.findu.analytics.AnalyticsHelper
+import com.kuit.findu.analytics.logUserSignIn
import com.kuit.findu.domain.usecase.SetNicknameUseCase
import com.kuit.findu.domain.usecase.auth.PostGuestLoginUseCase
import com.kuit.findu.domain.usecase.auth.PostLoginUseCase
@@ -19,7 +21,8 @@ class LoginViewModel @Inject constructor(
private val loginUseCase: PostLoginUseCase,
private val guestLoginUseCase: PostGuestLoginUseCase,
private val setAccessTokenUseCase: SetAccessTokenUseCase,
- private val setNicknameUseCase: SetNicknameUseCase
+ private val setNicknameUseCase: SetNicknameUseCase,
+ private val analyticsHelper: AnalyticsHelper,
) : ViewModel() {
private val _startMainActivity = MutableSharedFlow()
val startMainActivity: SharedFlow = _startMainActivity
@@ -34,6 +37,9 @@ class LoginViewModel @Inject constructor(
if (loginData.isFirstLogin) {
startOnboardingActivity(kakaoId = kakaoId)
} else {
+ analyticsHelper.logUserSignIn(
+ userName = loginData.userInfo?.nickname ?: "Null Nickname", type = "kakao"
+ )
setAccessTokenUseCase(accessToken = loginData.userInfo!!.accessToken)
setNicknameUseCase(nickname = loginData.userInfo.nickname)
startMainActivity()
@@ -44,11 +50,11 @@ class LoginViewModel @Inject constructor(
}
}
-
fun postGuestLogin(onSuccess: () -> Unit) {
viewModelScope.launch {
guestLoginUseCase.postGuestLogin()
.onSuccess { loginData ->
+ analyticsHelper.logUserSignIn(userName = GUEST_NAME, type = "Guest")
setAccessTokenUseCase(accessToken = loginData.accessToken)
setNicknameUseCase(nickname = GUEST_NAME)
onSuccess()
@@ -61,7 +67,6 @@ class LoginViewModel @Inject constructor(
}
-
private fun startMainActivity() {
viewModelScope.launch {
_startMainActivity.emit(Unit)
diff --git a/app/src/main/java/com/kuit/findu/presentation/ui/main/MainActivity.kt b/app/src/main/java/com/kuit/findu/presentation/ui/main/MainActivity.kt
index 4581d6f3..f1cc619f 100644
--- a/app/src/main/java/com/kuit/findu/presentation/ui/main/MainActivity.kt
+++ b/app/src/main/java/com/kuit/findu/presentation/ui/main/MainActivity.kt
@@ -7,22 +7,22 @@ import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.setupWithNavController
import com.kuit.findu.R
+import com.kuit.findu.analytics.AnalyticsHelper
+import com.kuit.findu.analytics.logScreenView
import com.kuit.findu.databinding.ActivityMainBinding
import dagger.hilt.android.AndroidEntryPoint
+import javax.inject.Inject
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
-
+ @Inject
+ lateinit var analyticsHelper: AnalyticsHelper
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
-
-
-
-
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
@@ -39,6 +39,14 @@ class MainActivity : AppCompatActivity() {
private fun setBottomNaviVisible(navController: NavController) {
navController.addOnDestinationChangedListener { _, destination, _ ->
+ val screenName = try {
+ resources.getResourceEntryName(destination.id)
+ } catch (_: Exception) {
+ "unknown_screen"
+ }
+
+ analyticsHelper.logScreenView(screenName)
+
binding.bnvMain.visibility = when (destination.id) {
R.id.fragment_home, R.id.fragment_search, R.id.fragment_info, R.id.fragment_my -> View.VISIBLE
R.id.fragment_search_detail_witness, R.id.fragment_search_detail_disappear, R.id.fragment_search_detail_protecting -> View.VISIBLE
diff --git a/app/src/main/java/com/kuit/findu/presentation/ui/onboarding/viewmodel/OnboardingViewModel.kt b/app/src/main/java/com/kuit/findu/presentation/ui/onboarding/viewmodel/OnboardingViewModel.kt
index b3a0e52a..779f3b49 100644
--- a/app/src/main/java/com/kuit/findu/presentation/ui/onboarding/viewmodel/OnboardingViewModel.kt
+++ b/app/src/main/java/com/kuit/findu/presentation/ui/onboarding/viewmodel/OnboardingViewModel.kt
@@ -5,6 +5,8 @@ import android.net.Uri
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import com.kuit.findu.analytics.AnalyticsHelper
+import com.kuit.findu.analytics.logUserSignUp
import com.kuit.findu.domain.usecase.auth.PostCheckNicknameUseCase
import com.kuit.findu.domain.usecase.auth.PostSignupUseCase
import com.kuit.findu.presentation.type.DefaultProfileType
@@ -35,6 +37,7 @@ class OnboardingViewModel @Inject constructor(
@ApplicationContext private val context: Context,
private val postCheckNicknameUseCase: PostCheckNicknameUseCase,
private val postSignupUseCase: PostSignupUseCase,
+ private val analyticsHelper: AnalyticsHelper,
) : ViewModel() {
private val _uiState = MutableStateFlow(OnboardingUiState())
val uiState: StateFlow = _uiState.asStateFlow()
@@ -120,6 +123,7 @@ class OnboardingViewModel @Inject constructor(
nickname = uiState.value.nickname,
kakaoId = uiState.value.kakaoId
).onSuccess {
+ analyticsHelper.logUserSignUp(userName = uiState.value.nickname)
startMainActivity()
}.onFailure { e ->
Log.d("http", "Error Message: : $e")
diff --git a/app/src/main/java/com/kuit/findu/presentation/ui/report/WitnessReportFragment.kt b/app/src/main/java/com/kuit/findu/presentation/ui/report/WitnessReportFragment.kt
index 629549e5..45a17d99 100644
--- a/app/src/main/java/com/kuit/findu/presentation/ui/report/WitnessReportFragment.kt
+++ b/app/src/main/java/com/kuit/findu/presentation/ui/report/WitnessReportFragment.kt
@@ -59,7 +59,7 @@ class WitnessReportFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
-
+
resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == AppCompatActivity.RESULT_OK) {
val data = result.data?.getStringExtra(ReportLocationDialog.Companion.POST_TAG)
diff --git a/build.gradle.kts b/build.gradle.kts
index 309816ff..ebcb5dfd 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -4,5 +4,6 @@ plugins {
alias(libs.plugins.kotlin.android) apply false
alias(libs.plugins.dagger.hilt) apply false
alias(libs.plugins.navigationSafeArgs) apply false
- id("com.google.gms.google-services") version "4.4.2" apply false
+ alias(libs.plugins.googleServices) apply false
+ alias(libs.plugins.firebaseCrashlytics) apply false
}
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index bd319424..0e29bbf2 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -3,11 +3,10 @@ accompanistPermissions = "0.37.3"
agp = "8.7.3"
coilCompose = "2.5.0"
composeBom = "2024.04.01"
-firebaseBom = "34.4.0"
-firebaseBomVersion = "33.4.0"
-firebaseConfig = "23.0.1"
-googleFirebaseBom = "33.3.0"
-kotlin = "1.9.24"
+firebaseBom = "34.6.0"
+firebaseCrashlytics = "3.0.6"
+googleServices = "4.4.2"
+kotlin = "2.0.21"
coreKtx = "1.15.0"
junit = "4.13.2"
junitVersion = "1.2.1"
@@ -37,8 +36,6 @@ playServicesLocation = "21.3.0"
cameraCore = "1.4.1"
kakao = "2.20.3"
material3Android = "1.3.2"
-firebaseCommonKtx = "22.0.1"
-
[libraries]
accompanist-permissions = { module = "com.google.accompanist:accompanist-permissions", version.ref = "accompanistPermissions" }
@@ -51,16 +48,13 @@ androidx-ui-tooling = { module = "androidx.compose.ui:ui-tooling" }
androidx-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview" }
androidx-webkit = { module = "androidx.webkit:webkit", version.ref = "webkit" }
coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coilCompose" }
-firebase-analytics = { module = "com.google.firebase:firebase-analytics" }
-firebase-analytics-ktx = { module = "com.google.firebase:firebase-analytics-ktx" }
+
+# Firebase
firebase-bom = { module = "com.google.firebase:firebase-bom", version.ref = "firebaseBom" }
-firebase-bom-v3330 = { module = "com.google.firebase:firebase-bom", version.ref = "googleFirebaseBom" }
-firebase-bom-v3340 = { module = "com.google.firebase:firebase-bom", version.ref = "firebaseBomVersion" }
-firebase-config = { module = "com.google.firebase:firebase-config" }
-firebase-config-ktx = { module = "com.google.firebase:firebase-config-ktx" }
-google-firebase-analytics = { module = "com.google.firebase:firebase-analytics" }
-google-firebase-config = { module = "com.google.firebase:firebase-config", version.ref = "firebaseConfig" }
-google-firebase-config-ktx = { module = "com.google.firebase:firebase-config-ktx" }
+firebase-analytics-ktx = { module = "com.google.firebase:firebase-analytics" }
+firebase-config-ktx = { module = "com.google.firebase:firebase-config" }
+firebase-crashlytics = { module = "com.google.firebase:firebase-crashlytics"}
+
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
@@ -101,14 +95,16 @@ kakao-friend = { group = "com.kakao.sdk", name = "v2-friend", version.ref = "kak
kakao-navi = { group = "com.kakao.sdk", name = "v2-navi", version.ref = "kakao" }
kakao-cert = { group = "com.kakao.sdk", name = "v2-cert", version.ref = "kakao" }
androidx-material3-android = { group = "androidx.compose.material3", name = "material3-android", version.ref = "material3Android" }
-firebase-common-ktx = { group = "com.google.firebase", name = "firebase-common-ktx", version.ref = "firebaseCommonKtx" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
+kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
dagger-hilt = { id = "com.google.dagger.hilt.android", version.ref = "daggerHilt" }
navigationSafeArgs = { id = "androidx.navigation.safeargs.kotlin", version.ref = "navigationFragmentKtx" }
+googleServices = { id = "com.google.gms.google-services", version.ref = "googleServices" }
+firebaseCrashlytics = { id = "com.google.firebase.crashlytics", version.ref = "firebaseCrashlytics" }
[bundles]
hilt = [