[Feat] FirebaseAnalytics 로그 수집 - #192
Conversation
* **feat: `FirebaseAnalytics` 클래스화 및 의존성 주입 적용**
* 기존 `object` 선언을 `class`로 변경하고 Metro를 통한 의존성 주입(`@Inject`)을 적용했습니다.
* `FestivalLocalDataSource` 및 `DeviceLocalDataSource`를 주입받아 축제 ID와 사용자 UUID를 자동으로 수집하도록 개선했습니다.
* **feat: 기본 이벤트 파라미터 자동 설정 및 지연 전송 로직 구현**
* 앱 버전, OS 버전, 디바이스 모델, 언어, 사용자 ID 등을 포함하는 기본 파라미터를 `setDefaultEventParameters`를 통해 설정합니다.
* 초기화 작업이 완료되기 전 발생한 이벤트를 `Channel`에 보관했다가 초기화 후 순차적으로 전송하는 `PendingEvent` 처리 로직을 추가했습니다.
* 모든 이벤트 로깅 시 현재 활성화된 `festival_id`가 자동으로 포함되도록 수정했습니다.
* **refactor: 플랫폼별 분석 로직 고도화 및 불필요한 메서드 제거**
* **Android**: `Firebase.analytics`를 활용하여 기본 파라미터 및 `festival_id` 매핑 로직을 구현했습니다.
* **iOS**: `utsname`을 사용한 상세 디바이스 모델 추출 및 `NSDate` 기반 타임스탬프 계산 로직을 추가했습니다.
* 사용되지 않는 `getAppInstanceId`, `getSessionId` 메서드를 제거했습니다.
* **infra: 앱 그래프 내 분석 서비스 등록**
* `FestabookAppGraph`에 `FirebaseAnalytics`를 추가하고, 비동기 작업을 위한 `IOCoroutineScope` 제공 로직을 구성했습니다.
# Conflicts:
# composeApp/src/commonMain/kotlin/com/daedan/festabook/di/FestabookAppGraph.kt
* **feat: 공통 시간 측정 유틸리티 `currentTimeMillis` 구현**
* Kotlin Multiplatform의 `expect/actual`을 사용하여 플랫폼별 현재 시간(ms) 측정 로직을 통합했습니다.
* **Android**: `System.currentTimeMillis()`를 사용합니다.
* **iOS**: `NSDate`와 `timeIntervalSince1970`을 사용하여 구현하고, 기존 `IosFirebaseAnalytics` 내 중복 코드를 제거했습니다.
* **feat: 알림 클릭 시 분석 이벤트(`notification_tapped`) 로깅 추가**
* `FcmDeepLinkAction.OpenAnnouncement` 모델에 `notificationSentAt` 필드를 추가하여 알림 발송 시점을 기록합니다.
* 알림 클릭 핸들러에서 알림 ID, 발송 시점, 그리고 클릭까지 걸린 시간(`elapsed_sec`)을 포함한 분석 이벤트를 전송하도록 구현했습니다.
* `MainScreen` 진입 시 `app_foreground` 이벤트를 로깅하도록 추가했습니다.
* **refactor: 분석 도구 및 딥링크 처리 로직 개선**
* `rememberAnalytics()` Composable을 추가하여 `AppGraph`에서 `FirebaseAnalytics` 인스턴스를 쉽게 참조할 수 있도록 개선했습니다.
* Android 및 iOS의 메시징 서비스/델리게이트에서 공지사항 알림 처리 시 현재 타임스탬프를 함께 전달하도록 수정했습니다.
* `AndroidFirebaseAnalytics`에서 기본 파라미터 설정 시 새로 정의한 `currentTimeMillis()`를 사용하도록 통일했습니다.
* **feat: 클릭 이벤트 로깅을 위한 `Modifier.logClick` 확장 함수 추가**
* `Modifier.clickable`을 래핑하여 버튼 클릭 시 `button_id`와 `screen_name` 파라미터를 포함한 `button_click` 이벤트를 자동으로 전송합니다.
* **feat: 화면 진입 및 이탈 로깅을 위한 `ScreenViewLogger` 컴포저블 구현**
* `DisposableEffect`를 활용해 화면 진입(`screen_view`)과 이탈(`screen_exit`) 시점을 기록합니다.
* 이탈 시 화면 체류 시간(`duration_sec`)을 계산하여 함께 전송하도록 로직을 구성했습니다.
* **feat: 가시성 기반 로깅을 위한 `ScreenViewVisibilityLogger` 구현**
* `isVisible` 상태 변화에 따라 화면 노출 여부를 판단하여 진입/이탈 이벤트를 전송합니다.
* 체류 시간을 소수점 단위의 초(`Double`)로 정밀하게 계산하도록 구현했습니다.
* **feat: `DeepLinkKeys` 내 알림 전송 시각 키 정의**
* 딥링크 데이터 관리를 위한 `KEY_NOTIFICATION_SENT_AT` 상수를 추가했습니다.
* **feat: `NotificationHelper` 알림 생성 시 현재 시각 포함**
* 공지사항 알림(`ANNOUNCEMENT`) 생성 시, 인텐트에 현재 시각(`currentTimeMillis()`)을 `KEY_NOTIFICATION_SENT_AT`에 담아 전달하도록 수정했습니다.
* **refactor: `RememberDeepLinkHandler` 내 알림 시각 추출 및 처리 로직 반영**
* 안드로이드 인텐트에서 `notificationSentAt` 값을 추출하여 `FcmDeepLinkAction.OpenAnnouncement`로 전달하도록 수정했습니다.
* 처리가 완료된 `KEY_NOTIFICATION_SENT_AT` 데이터를 인텐트에서 제거하는 로직을 추가했습니다.
* **feat: 주요 화면에 `ScreenViewLogger` 및 `ScreenViewVisibilityLogger` 추가**
* `HomeScreen`, `PlaceMapScreen`, `NewsScreen`, `ScheduleScreen`, `SettingScreen` 등 거의 모든 주요 화면(Screen) 컴포넌트에 진입 시 로그를 남기는 `ScreenViewLogger`를 추가했습니다.
* `PlaceMapScreen`에는 가시성 상태에 따라 로깅 여부를 결정하는 `ScreenViewVisibilityLogger`를 적용했습니다.
* **feat: `logClick` 함수 내 추가 파라미터(`extraParam`) 지원**
* 버튼 클릭 로그를 기록할 때 기존 `button_id`와 `screen` 외에도 사용자 정의 매개변수를 추가로 전달할 수 있도록 `extraParam` 파라미터를 추가했습니다.
* `buildMap`을 사용하여 로그 이벤트에 포함될 데이터 구조를 확장했습니다.
* **style: `FestaingScreen` 내 오타 수정**
* `ScreenViewLogger`에 전달되는 문자열 내 오타를 수정했습니다. (`FestaingScreen`)
* **refactor: `ScreenViewLogger` 내 상태 관리 및 코드 정리**
* `enteredTime`을 저장할 때 일반 `mutableStateOf<Long>` 대신 `mutableLongStateOf`를 사용하도록 변경하여 오토박싱을 방지했습니다.
* 파일 끝의 불필요한 공백을 제거했습니다.
* **refactor: `IosFirebaseAnalytics` 의존성 주입 수정 및 미사용 임포트 제거**
* `CoroutineScope` 주입 시 `@IO` 한정자(qualifier)를 추가하여 적절한 스코프가 주입되도록 명시했습니다.
* `NSDate`, `date`, `timeIntervalSince1970` 등 iOS 플랫폼의 미사용 임포트를 정리했습니다.
* **style: 코드 포맷팅 및 미사용 임포트 제거**
* `ClickableLogger.kt`: `logEvent` 호출 시 가독성을 위해 파라미터 줄바꿈 및 트레일링 콤마를 추가했습니다.
* `AndroidAppGraph.kt`, `RememberDeepLinkHandler.android.kt`: 불필요한 임포트 구문을 제거했습니다.
* `FestabookAppGraph.kt`: 불필요한 빈 줄을 제거했습니다.
* `FestatingScreen.kt`: 임포트 순서를 조정했습니다.
* **feat: `FAQScreen`, `NoticeScreen` 내 아이템 클릭 로깅**
* FAQ 및 공지사항 항목 클릭 시 각각 `faq_id`, `notice_id`를 포함하여 로깅하도록 수정했습니다.
* 공지사항 및 유실물 화면의 새로고침 액션에 로깅을 추가했습니다.
* **feat: `HomeScreen` 및 메인 내비게이션 클릭 로깅**
* 홈 화면에서 탐색, 페스타팅, 일정, 웨이팅 바 클릭 시 로깅을 수행합니다.
* 하단 탭 바에서 각 탭 선택 시 탭 이름을 포함하여 로깅하도록 개선했습니다.
* **feat: 장소 관련 화면 클릭 로깅**
* 장소 지도(`PlaceMapScreen`)의 카테고리 선택 및 리스트 아이템 클릭 시 로깅을 추가했습니다.
* 장소 상세 및 미리보기 화면에서 상세 이동, 웨이팅 등록 등의 액션 로깅을 수행합니다.
* **feat: 웨이팅 및 설정 화면 액션 로깅**
* `MyWaitingScreen`의 새로고침, 취소, 상세 이동 액션에 로깅을 적용했습니다.
* 웨이팅 등록 화면의 인원 조절, 약관 동의, 등록 버튼 클릭 시 로깅을 수행합니다.
* 설정 화면의 공지사항/정책 링크 클릭, 알림 설정 토글, 내 정보 저장 액션 등에 로깅을 추가했습니다.
* **feat: 검색 및 뒤로가기 액션 로깅**
* 탐색 화면(`ExploreScreen`) 및 각 주요 화면의 뒤로가기 버튼 클릭 시 로깅을 수행하도록 수정했습니다.
ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Free Run ID: 📒 Files selected for processing (40)
💤 Files with no reviewable changes (3)
📝 Walkthrough훑어보기이 PR은 멀티플랫폼 expect/actual 객체에서 플랫폼 인식 추상 클래스 아키텍처로 Firebase Analytics를 리팩토링하고, 알림 타임스탬프를 딥링크 플로우에 통합하면서 UI 레이어 전반에 걸쳐 포괄적인 화면 조회 및 클릭 이벤트 로깅을 추가합니다. 변경 사항분석 인프라 리팩토링 및 UI 로깅 계측
Sequence DiagramsequenceDiagram
participant App as App
participant Analytics as FirebaseAnalytics<br/>(Abstract)
participant Platform as Platform<br/>(Android/iOS)
participant Firebase as Firebase SDK
participant LocalData as LocalDataSources
App->>Analytics: initialize(scope, dataSource)
activate Analytics
Note over Analytics: Create pending event channel<br/>& launch initializingJob
Analytics->>Platform: setDefaultEventParameters()
activate Platform
Platform->>LocalData: getFestivalId(), getUuid()
LocalData-->>Platform: festival_id, user_id
Platform->>Firebase: setDefaultEventParameters(params)
Firebase-->>Platform: ✓
deactivate Platform
Analytics->>Analytics: flushPendingEvents()
deactivate Analytics
App->>App: render UI with ScreenViewLogger/logClick
App->>Analytics: logEvent("button_click", params)
activate Analytics
alt initializingJob.isCompleted
Analytics->>Platform: onLogEvent("button_click", merged_params)
activate Platform
Platform->>Firebase: logEvent("button_click", {..., festival_id})
deactivate Platform
else still initializing
Analytics->>Analytics: buffer event to pending channel
end
deactivate Analytics
예상 코드 리뷰 난이도🎯 4 (Complex) | ⏱️ ~60 분 시
Note 🎁 Summarized by CodeRabbit FreeYour organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login. Review rate limit: 2/3 reviews remaining, refill in 20 minutes. Comment |
#️⃣ 이슈 번호
🛠️ 작업 내용
🙇🏻 중점 리뷰 요청
📸 이미지 첨부 (Optional)
Summary by CodeRabbit
릴리스 노트
새로운 기능
버그 수정