Firebase Remote Config로 배포 없이 값 "딸깍" 바꿔주기

2025. 11. 23. 12:28·실무 내용 내껄로 만들기

앱에 새로 출시할 기능이 상당히 실험적이고 도전적이라 '어떤 비즈니스 이펙트를 가져올지 예상할 수 없을 때' 어떤 선택을 할 수 있을까요? 여기서 전제는 '앱 배포'이기 때문에 되돌리거나 새로운 변경사항으로 바꾸고 싶으면 기존 방식으로는 길고 긴 심사를 다시 거쳐야한다는 것입니다.

  1. 점진 배포하기
  2. Server-Driven 방식으로 분기처리 하기
  3. 그냥 다시 배포하고 기도하기(?)

3가지 방식 모두 장단점이 있지만, 오늘은 그 중에서도 가장 적은 리소스로 가장 빠르게 프론트에서 적용할 수 있는 방식인 Firebase Remote Config 방식에 대해 정리해보겠습니다.

 

Firebase Remote Config?

이름에서도 알 수 있듯 원격 제어 설정을 도와주는 친구입니다.(Firebase,,, 대체 얼마나 해주는거야!!) 공식 개발자 문서에 따르면 아래와 같은 기능을 도입할 수 있다고 해요.

  • 앱 사용자 층에 변경사항을 빠르게 출시: 파라미터 값을 원격으로 바꿔 앱 내 변화.
  • 사용자층의 특정 세그먼트에 앱 맞춤설정: GA 세그먼트를 기준으로 다양한 사용자 환경 제공 가능.
  • 타겟팅 및 점진 배포, 커스텀 이벤트 측정, A/B 테스트 설정 등등...

원격으로 값을 바꿔줄 수 있기 때문에 Server-Driven 방식처럼 분기 처리로 배포와 상관 없이 앱 내 변화를 줄 수 있게 됩니다. 이렇게 좋은 기능이 있었는데,,, 왜 작년엔 서버 없다고 3번 방식(기도 메타)만 사용했는지 모르겠네요.

 

일단 한번 해보기(빠른 시작 가이드)

기본적으로 프로젝트 내 Firebase 세팅이 되어있다는 걸 기준으로 정리해보겠습니다.(안했다면 요 공식 문서를!) 또 Remote Config 사용을 위해선 Google Analytics 사용 설정도 필수이기 때문에 이 친구 또한 되어 있어야 합니다.(안했다면 요 공식 문서를!)

 

자 우선 어떤 값을 원격으로 사용하고 제어하고 싶은지 명시해야겠죠? Firebase Console에서 쉽게 설정할 수 있습니다.

실행 > Remote Config

Remote Config를 처음 설정하게 되면 아래 화면으로 진입하게 됩니다. 첫 구성을 만들기 위해 '구성 만들기' 버튼을 클릭합니다.

'구성 만들기' 버튼 클릭

이제 매개변수를 만들면 됩니다! 필드도 몇개 없고 직관적이라 어떤 값들이 들어가야 할지 쉽게 파악이 가능합니다. 저는 제 강아지 이름을 원격으로 제어하고자 `puppy_name`의 Key와 '민톨'이라는 Value를 문자열 타입으로 설정해주었습니다.

 

++ 중요! Remote Config 파라미터 Key 또는 Value에는 민감한 데이터를 저장하지 말 것을 권장합니다.

이렇게 첫 번째 매개변수를 만들고 나면 앞으로 계속 보게될 매개변수 리스트 화면을 볼 수 있게 됩니다. 여기서 중요한 점은, 값을 만들면 바로 반영되는 것이 아닌 '변경 사항 게시' 버튼을 눌러줘야 실제 값이 반영된다는 것입니다! 잊지말고 꼭 눌러주세요.

Firebase Console에서의 설정은 끝났습니다. 이제 프로젝트에도 Remote Config를 가져오기 위한 기본 세팅을 진행해줍니다. 먼저 제가 기존에 사용하던 `FirebaseManager`에 이를 위한 함수를 하나 생성해주었습니다.

 

++ `import FirebaseRemoteConfig` 부분에서 컴파일 에러가 난다면, 프로젝트 타겟에 `FirebaseRemoteConfig`가 추가되었는지 확인해보세요!(없다면 추가 고고)

import FirebaseCore
import FirebaseRemoteConfig // ⭐️ 추가

enum FirebaseManager {
    
    /// Firebase를 초기화합니다.
    static func initialize() {
        FirebaseApp.configure()
    }
    
    /// ⭐️ Remote Config를 설정합니다.
    static func setupRemoteConfig() {
        let remoteConfig = RemoteConfig.remoteConfig() // ⭐️ 싱글톤
        let settings = RemoteConfigSettings() // ⭐️ 설정 객체
        settings.minimumFetchInterval = 0 // ⭐️ 얼마나 자주 값을 가져올지(0 == 최대한 자주)
        remoteConfig.configSettings = settings // ⭐️ 싱글톤에 설정 객체 넘기기
    }
}

이후 앱 초기화 시점에 Firebase 초기화와 함께 RemoteConfig 설정도 진행해주었습니다.

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        // ...
        FirebaseManager.initialize()
        FirebaseManager.setupRemoteConfig() // ⭐️ 앱 초기화 시 Remote Config 설정
        // ...
    }
}

 

자 이제 대망의 값을 가져와보겠습니다! Firebase Console에서 작성했던 Key와 타입을 이용해 아래와 같이 작성하면 우리가 설정했던 '민톨' 값을 정상적으로 가져오는 것을 확인할 수 있습니다.

// ⭐️ 당연한 이야기지만 비동기로 가져오지 않으면 기본값(타입 기본값 or 내가 지정한 기본값)으로 설정됨
Task {
    let remoteConfig = RemoteConfig.remoteConfig()
    try await remoteConfig.fetch()
    try await remoteConfig.activate()
    let puppyName = remoteConfig["puppy_name"].stringValue
    print("제 강아지 이름은 \(puppyName)이에요.")
}

 

다양한 타입 설정도 가능해요

Remote Config는 총 4개의 데이터 타입을 지원합니다. 위에서 예시로 포함한 문자열(`String`)과 숫자(`Int`), 부울(`Bool`), `JSON`을 이용해 다양한 데이터를 표현할 수 있죠. 각각 사용은 아래와 같이 가능합니다. JSON을 지원하기 때문에 사실상 대부분의 데이터는 모두 표현이 가능하다 봐도 무방합니다 ㅎㅎ

Task {
    let remoteConfig = RemoteConfig.remoteConfig()
    try await remoteConfig.fetch()
    try await remoteConfig.activate()
    let puppyName = remoteConfig["puppy_name"].stringValue
    let puppyAge = remoteConfig["puppy_age"].numberValue
    let isCute = remoteConfig["isCute"].boolValue
    let character = try remoteConfig["character"].decoded(asType: Character.self)
    print("제 강아지 이름은 \(puppyName)이고 \(puppyAge)살이고 \(isCute ? "귀여워요" : "별로에요").")
    dump(character)
}

 

인앱 기본값 설정도 가능해요

지금가지는 Firebase Console에서 기본값을 설정해주었지만 각각의 앱 별로 별도의 기본값을 사용해줘야 할 일이 생기기도 합니다.(ex: iOS, Android에 따른 기본값 분기 처리 등)

 

인앱 기본값을 설정하기 위해 Firebase Console에서 기본값 파일을 다운로드 받은 후, 앱 내 적용해 이를 구현할 수 있습니다.

원격 구성 기본값을 다운로드 받으면 `remote_config_defaults.plist` 파일이 다운로드 됩니다. 해당 파일을 프로젝트에 적용 후, 설정하고 싶은 기본값을 구성합니다.

static func setupRemoteConfig() {
    let remoteConfig = RemoteConfig.remoteConfig()
    let settings = RemoteConfigSettings()
    settings.minimumFetchInterval = 0
    remoteConfig.configSettings = settings
    remoteConfig.setDefaults(fromPlist: "remote_config_defaults") // ⭐️ 기본값 설정
}

그럼 이렇게 안귀여운(?) 한톨을 출력할 수 있게 됩니다.

 

실시간 업데이트도 가능해요

지금까지 RemoteConfig를 받아오는 방식은 매번 명시적으로 불러오는 것이었습니다.(ex: viewDidLoad, onAppear 시점에 RemoteConfig 값 호출)

 

하지만 Rx나 Combine, AsyncStream처럼 비동기 스트림 형태, 즉 실시간으로 값을 받을 수 있는 방법도 있습니다!

// ⭐️ Remote Config 리스너 추가
remoteConfig.addOnConfigUpdateListener { configUpdate, error in

    // ⭐️ 에러 처리
    if let error {
        print("에러 발생: \(error.localizedDescription)")
        return
    }
    
    // ⭐️ 업데이트가 있을 시 로직 호출
    if let _ = configUpdate {
        Task {
            let remoteConfig = RemoteConfig.remoteConfig()
            try await remoteConfig.fetch()
            try await remoteConfig.activate()
            let puppyName = remoteConfig["puppy_name"].stringValue
            print("실시간 민톨 이름 업데이트: \(puppyName)")
        }
    }
}

민톨이는 100세까지 살자

 

SwiftUI용 프로퍼티 래퍼도 있어요

일반 함수 안에서는 위와 같이 리스너를 추가해 실시간 값을 받아올 수 있지만, SwiftUI View 용으로만 사용한다면 전용 프로퍼티 래퍼 `@RemoteConfigProperty` 사용을 고려해봐도 좋습니다. 아래와 같이 추가하면 정말 쉽게 실시간 View 업데이트를 사용할 수 있게 됩니다!

struct ContentView: View {
  @RemoteConfigProperty(key: "puppy_name", fallback: "기본 민톨") var puppyName

  var body: some View {
    VStack {
      Text(puppyName)
    }
    .onAppear {
      RemoteConfig.remoteConfig().fetchAndActivate()
    }
  }
}

 

역시 좋은 기능은 잘 찾아오면 이미 있다,,, ㅎㅎ

최근 회사 프로젝트에서 광고 SDK 관련 민감한 로직의 분기 처리를 빠르게 적용하기 위해 Sever-Driven 대신 Firebase Remote Config를 사용했었습니다. 이미 여기저기 사용 중이었기 때문에 이미 있던 값들을 가져다 쓰기만 했었는데, 역시 이렇게 직접 구현해보니 더 제 것이 되는 것 같습니다.

 

예전 캐플 프로젝트 때도 Remote Config를 적극적으로 활용했으면 서버 분들께 부담 드리지 않고 다양한 이벤트를 진행해 볼 수 있었을 것 같다는 아쉬움도 남네요 ㅜ 🥲

저작자표시 (새창열림)

'실무 내용 내껄로 만들기' 카테고리의 다른 글

Firebase App Distribution + Fastlane으로 초간단 QA 빌드 뽑아보기  (0) 2025.10.19
Git Worktree로 브랜치 사이를 효율적으로 거닐기  (0) 2025.09.13
무지성 Commit은 그만! Git Rebase로 깔끔하게 코드 리뷰 반영하기  (5) 2025.09.07
'실무 내용 내껄로 만들기' 카테고리의 다른 글
  • Firebase App Distribution + Fastlane으로 초간단 QA 빌드 뽑아보기
  • Git Worktree로 브랜치 사이를 효율적으로 거닐기
  • 무지성 Commit은 그만! Git Rebase로 깔끔하게 코드 리뷰 반영하기
thinkyside
thinkyside
스스로에게 솔직해지고 싶은 공간
  • thinkyside
    또 만드는 한톨
    thinkyside
  • 전체
    오늘
    어제
    • 모아보기 (70)
      • 솔직해보려는 회고 (1)
      • 꾸준히 글쓰기 (10)
      • 생각을 담은 독서 (8)
      • 내게 필요한 개발 공부 (25)
      • 실무 내용 내껄로 만들.. (4)
      • 트러블슈팅 (4)
      • 프로젝트 일지 (9)
      • 개발 서적 (3)
      • 취준 (3)
      • 대외활동 (2)
      • UXUI (1)
  • hELLO· Designed By정상우.v4.10.3
thinkyside
Firebase Remote Config로 배포 없이 값 "딸깍" 바꿔주기
상단으로

티스토리툴바