Firebase Remote Config로 데모 앱 유효기간 관리하기 – 빌드 시간 기반 자동 만료 시스템

최근에 회사에서 SDK 데모 앱을 만들면서 겪은 일입니다. 무제한으로 사용하게 둘 수는 없고… 그렇다고 매번 만료일을 하드코딩해서 빌드하기도 번거롭더라구요.

그래서 Firebase Remote Config를 활용해서 꽤 괜찮은 해결책을 만들었습니다. 오늘은 그 과정을 공유해보려고 합니다.

문제 상황

저희가 원했던 건 이런 거였어요:

  • 빌드할 때마다 자동으로 3일 사용 기한 설정
  • “며칠만 더 써보고 싶다”고 하면 즉시 연장 가능
  • 문제 생기면 바로 사용 중지
  • 앱 재배포 없이 모든 걸 제어

처음엔 SharedPreferences에 첫 실행 날짜를 저장하는 방법도 생각해봤는데, 앱 삭제하고 재설치하면 리셋되는 문제가 있더라구요. 서버 구축은 오버엔지니어링 같았고…

해결 방법: 빌드 타임스탬프 + Remote Config

결국 이렇게 해결했습니다:

1. 빌드 시점 자동 기록

먼저 build.gradle.kts에서 빌드할 때마다 타임스탬프를 자동으로 기록하도록 설정했어요.

android {
    defaultConfig {
        buildConfigField("long", "BUILD_TIMESTAMP", "${System.currentTimeMillis()}L")
    }
}

이제 앱에서 BuildConfig.BUILD_TIMESTAMP로 언제 빌드됐는지 알 수 있습니다.

2. Firebase Remote Config 설정

Firebase Console에서 이런 값들을 설정했습니다:

{
  "demo_duration_days": 3,
  "demo_enabled": true
}

심플하죠? 기본 3일이고, 필요하면 언제든 바꿀 수 있어요.

3. 만료 체크 로직 구현

핵심 로직은 이렇습니다:

class DemoExpiryManager(private val remoteConfig: FirebaseRemoteConfig) {
    
    fun checkDemoExpiry(callback: (Boolean, String?) -> Unit) {
        remoteConfig.fetchAndActivate()
            .addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    val isExpired = isDemoExpired()
                    val message = if (isExpired) "데모 기간이 만료되었습니다." else null
                    callback(isExpired, message)
                }
            }
    }
    
    private fun isDemoExpired(): Boolean {
        // Remote Config에서 활성화 여부 먼저 체크
        if (!remoteConfig.getBoolean("demo_enabled")) {
            return true
        }
        
        // 빌드 시간 + 데모 기간으로 만료일 계산
        val demoDays = remoteConfig.getLong("demo_duration_days")
        val buildTime = BuildConfig.BUILD_TIMESTAMP
        val expiryTime = buildTime + (demoDays * 24 * 60 * 60 * 1000L)
        
        return System.currentTimeMillis() > expiryTime
    }
}

MainActivity에서는 이렇게 사용해요:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    
    demoExpiryManager.checkDemoExpiry { isExpired, message ->
        if (isExpired) {
            // 만료 다이얼로그 표시 후 앱 종료
            showExpiryDialog(message)
        }
    }
}

가장 좋은 점은 앱을 다시 빌드하거나 배포할 필요가 없다는 거예요. Firebase Console에서 숫자 하나만 바꾸면 끝!

꿀팁 몇 가지

실제로 써보면서 알게 된 팁들:

  1. 빌드 타입별 관리: Remote Config에 JSON으로 빌드 타입 별로 만료일을 따로 관리할 수도 있어요.
  2. 남은 기간 표시: 앱 하단에 작게 “3일 남음” 같은 걸 표시하면 사용자도 알 수 있어서 좋아요.
  3. 캐시 주기 설정: minimumFetchIntervalInSeconds를 1시간 정도로 설정하면 적당해요.

테스트 코드 작성할 때 주의점

Unit Test 작성할 때 Tasks.forResult() 쓰면 Android Looper 때문에 에러나더라구요. MockK로 Task를 완전히 mocking해야 합니다:

val mockTask = mockk<Task<Boolean>>()
every { mockTask.isSuccessful } returns true
every { mockTask.addOnCompleteListener(any()) } answers {
    firstArg<OnCompleteListener<Boolean>>().onComplete(mockTask)
    mockTask
}

이거 때문에 한참 헤맸네요 ㅠㅠ

무엇보다 서버 구축 없이 이런 시스템을 만들 수 있다는 게 큰 장점인 것 같아요. 혹시 비슷한 고민 있으신 분들께 도움이 되었으면 좋겠습니다!

질문 있으시면 댓글로 남겨주세요 🙂

Leave a Comment