Skip to content

Feature/firebase event#53

Merged
Roy-wonji merged 10 commits intomainfrom
feature/firebaseEvent
Dec 12, 2025
Merged

Feature/firebase event#53
Roy-wonji merged 10 commits intomainfrom
feature/firebaseEvent

Conversation

@Roy-wonji
Copy link
Contributor

🔗 관련 이슈

  • Firebase Analytics 이벤트 로깅 시스템 구현
  • Analytics 이벤트가 Firebase Console에 표시되지 않는 문제 해결

✨ 작업 내용

  • Firebase Analytics 통합: 앱 전반에 걸친 사용자 행동 추적 시스템 구현
  • Analytics 이벤트 추적: 로그인, 회원가입, 여행 관리 등 핵심 기능에 대한 이벤트 로깅 추가
  • 디버그 환경 설정: Firebase Analytics 디버그 모드 활성화 및 상세 로깅 구현
  • 의존성 주입 시스템: Analytics UseCase 및 Manager를 통한 클린 아키텍처 적용

📝 참고 사항

  • GoogleService-Info.plist에서 IS_ANALYTICS_ENABLED를 true로 설정하여 Analytics 활성화
  • 디버그 빌드에서 FIRAnalyticsDebugEnabled=1 환경변수로 실시간 로그 확인 가능
  • Firebase Console의 DebugView에서 실시간 이벤트 모니터링 가능

Motivation 🥳 (코드를 추가/변경하게 된 이유)

  • 사용자 행동 패턴 분석을 위한 Firebase Analytics 도입 필요
  • 로그인, 회원가입, 여행 관리 등 핵심 기능의 사용량 추적 요구사항
  • Firebase Console에서 이벤트가 표시되지 않는 문제 해결 필요

Key Changes 🔥 (주요 구현/변경 사항)

  1. Firebase Analytics 인프라 구축
  • FirebaseAnalyticsManager: Firebase Analytics API를 래핑한 실제 구현체
  • AnalyticsManaging: 의존성 주입을 위한 프로토콜 정의
  • AnalyticsUseCase: 도메인 레이어에서 사용하는 UseCase 패턴 적용
  1. 이벤트 추적 구현

// 로그인 성공 이벤트
trackLoginSuccess(socialType: "google", isFirst: false)

// 회원가입 성공 이벤트
trackSignupSuccess(socialType: "apple")

// 여행 관련 이벤트
trackTravelUpdate(travelId)
trackTravelDelete(travelId)

  1. 의존성 주입 설정
  • LiveDependencies.swift에 실제 Analytics Manager 주입
  • 각 Feature에서 @dependency(.analyticsUseCase) 사용
  1. 디버그 환경 설정

#if DEBUG
setenv("FIRAnalyticsDebugEnabled", "1", 1)
setenv("FIRDebugEnabled", "1", 1)
#endif

  1. 주요 파일 변경사항
  • 새로 추가: Data/Sources/Analytics/FirebaseAnalyticsManager.swift (+80 lines)
  • 새로 추가: Domain/Sources/UseCase/Analytics/ 패키지 전체
  • 수정: LoginFeature.swift - 로그인/회원가입 이벤트 추가
  • 수정: AppDelegate.swift - Firebase 설정 및 디버그 모드 활성화
  • 수정: LiveDependencies.swift - Analytics 의존성 주입 설정

To Reviewers 🙏 (리뷰어에게 전달하고 싶은 말)

  • Firebase Analytics 권한이 필요하니 Firebase Console 접근 권한 확인 부탁드립니다
  • 디버그 빌드에서 Firebase Console > Analytics > DebugView에서 실시간 이벤트 확인 가능합니다
  • #logDebug 매크로를 사용하여 디버그 로그를 추가했으니 릴리즈 빌드에서는 제거됩니다

Reference 🔗

Close Issues 🔒 (닫을 Issue)

  • Firebase Analytics 이벤트 로깅 시스템 구현 완료

- Adding Firebase Analytics SDK dependency
- Creating Analytics manager and use case infrastructure
- Implementing analytics tracking for various user actions (login, signup, travel management, deeplinks, etc.)
- Updating app configuration to support Firebase
- Version bump to 1.0.2
Copy link
Contributor

@Peter1119 Peter1119 left a comment

Choose a reason for hiding this comment

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

지금 드는 생각은
feature에서 하지 않고 많은 부분은
usecase에서 할 수도 있지 않을까라는 생각입니다.
그럼 의존성에 대한 것을 많이 줄 일 수도 있고요

func trackExpenseDelete(travelId: String, expenseId: String, source: String)
}

public struct NoOpAnalyticsManager: AnalyticsManaging {
Copy link
Contributor

Choose a reason for hiding this comment

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

NoOp..? 이게 무슨 뜻인가요 ??

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Peter1119 이거 firebase 의존성 해결 때매 만들어놨는데 제거 하겠습니다

Comment on lines +7 to +24
func trackDeeplinkOpen(deeplink: String, type: String)
func trackExpenseOpenDetail(travelId: String, expenseId: String, source: String)
func trackLoginSuccess(socialType: String, isFirst: Bool?)
func trackSignupSuccess(socialType: String)

// Travel
func trackTravelUpdate(_ travelId: String)
func trackTravelDelete(_ travelId: String)
func trackTravelLeave(travelId: String, userId: String?)
func trackTravelMemberLeave(travelId: String, memberId: String, role: String?)
func trackTravelOwnerDelegate(travelId: String, newOwnerId: String)

// Additional Events from CSV
func trackExpenseView(travelId: String, tab: String, expenseDate: String)
func trackExpenseCreateSuccess(travelId: String, expenseId: String, amount: Double, currency: String, category: String, payerId: String)
func trackExpenseCreateFailure(travelId: String, amount: Double, currency: String, category: String, payerId: String, errorCode: String)
func trackExpenseUpdate(travelId: String, expenseId: String, amount: Double, currency: String, category: String, payerId: String)
func trackExpenseDelete(travelId: String, expenseId: String, source: String)
Copy link
Contributor

Choose a reason for hiding this comment

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

인터페이스가 너무 많은데
하나로 줄이고 들어가는 데이터 타입을 여러개로 할 수 있지 않을까요 ?
예를 들면 들어가는 것을 enum으로 정의하고
enum의 연관값으로 파라미터를 넣으면 되지 않을까 싶습니다 ~!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Peter1119 해당은 enum 처리 했습니다

Comment on lines +4 to +21
public protocol AnalyticsUseCaseProtocol: Sendable {
func trackDeeplinkOpen(deeplink: String, type: String)
func trackExpenseOpenDetail(travelId: String, expenseId: String, source: String)
func trackLoginSuccess(socialType: String, isFirst: Bool?)
func trackSignupSuccess(socialType: String)
func trackTravelUpdate(_ travelId: String)
func trackTravelDelete(_ travelId: String)
func trackTravelLeave(travelId: String, userId: String?)
func trackTravelMemberLeave(travelId: String, memberId: String, role: String?)
func trackTravelOwnerDelegate(travelId: String, newOwnerId: String)
}

public struct AnalyticsUseCase: AnalyticsUseCaseProtocol {
private let manager: any AnalyticsManaging

public init(manager: any AnalyticsManaging) {
self.manager = manager
}
Copy link
Contributor

Choose a reason for hiding this comment

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

manager를 한번 더 감싼 의도를 알 수 있을까요 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Peter1119 현재 코드에서는 별다른 이점이 없어서 제거하는 것이 좋을 것 같습니다

Comment on lines +192 to +195
return .merge(
.send(.delegate(.trackExpenseOpenDetail(travelId: travelId, expenseId: expenseId, source: "deeplink"))),
.send(.router(.routeAction(id: routeIndex, action: .settlementCoordinator(.navigateToExpenseTab(expenseId)))))
)
Copy link
Contributor

Choose a reason for hiding this comment

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

delegate는 상위에 요청하는 것이고 scope는 자식에게 요청할때 쓰는 단어가 아니었나요 ?
그리고 coordinator에서 tracking요청에 대한 action을 주입하는건 너무 과한 것 같아요
DelegateAction의 정의도 달라지는게 좋겟네요 .

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Peter1119 해당 내용 수정 했습니다

@Roy-wonji Roy-wonji requested a review from Peter1119 December 12, 2025 01:35
…/firebaseEvent

# Conflicts:
#	Features/Travel/Sources/Reducer/MemberSettingFeature.swift
Copy link
Contributor

@minneee minneee left a comment

Choose a reason for hiding this comment

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

고생하셨습니다!

Copy link
Contributor

@Peter1119 Peter1119 left a comment

Choose a reason for hiding this comment

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

고생하셨습니다 ~!

@Roy-wonji Roy-wonji merged commit ee05369 into main Dec 12, 2025
@Roy-wonji Roy-wonji deleted the feature/firebaseEvent branch December 12, 2025 02:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants