# Firebase User ID·User Property 설정

사용자 식별값은 Firebase Analytics setUserId로, 회원 등급·로그인 상태 같은 사용자 상태값은 setUserProperty로 설정하고 GA4 사용자 범위 맞춤 측정기준으로 등록하는 절차.

- 카테고리: Firebase
- 소요 시간: 약 7분
- 난이도: 중간
- 업데이트: 2026.06.22
- 원문: /wiki/playbook/firebase-checklist/how-to-set-firebase-user-properties

## 목차

- [이 문서의 목적](#purpose)
- [1단계 · 적용 대상 구분](#step-1)
- [2단계 · 속성 설계](#step-2)
- [3단계 · Android 코드](#step-3)
- [4단계 · iOS 코드](#step-4)
- [5단계 · WebView 연동](#step-5)
- [6단계 · GA4 등록](#step-6)
- [7단계 · DebugView 확인](#step-7)
- [참고 링크](#references)
- [자주 묻는 질문](#faq)

이 문서는 Firebase Analytics에서 **User ID**와 **User Property**를 설정하는 방법을 다룹니다. User ID는 사용자 식별이 필요할 때 `setUserId`로 별도 설정하고, 회원 등급·로그인 상태처럼 여러 이벤트를 가로질러 같은 사용자 상태로 분석해야 하는 값은 `setUserProperty`로 설정합니다.

> **이 문서 핵심**
>
> - Firebase SDK 초기화와 기본 이벤트 전송이 먼저 적용되어 있어야 합니다.
>
> - Android/iOS에서 같은 User ID 정책과 User Property 이름·값 체계를 사용합니다.
>
> - DebugView와 GA4 사용자 범위 맞춤 측정기준에서 사용자 상태값을 확인할 수 있습니다.

## 1단계. 이벤트 파라미터와 User Property 구분

먼저 값의 성격을 나눕니다. 행동 순간에만 의미가 있는 값은 이벤트 파라미터로 보내고, 사용자에게 일정 기간 유지되는 상태값은 User Property로 설정합니다.

| 구분 | 의미 | 예시 | 전송 방식 |
| --- | --- | --- | --- |
| 이벤트 파라미터 | 특정 이벤트의 상세 정보 | `method`, `search_term`, `item_id` | `logEvent`의 parameters |
| User Property | 사용자에게 붙는 현재 상태값 | `membership_level`, `login_status`, `user_type` | `setUserProperty` |
| User ID | 사용자 식별을 위한 별도 ID | 내부 회원 ID를 정책에 맞게 가공한 값 | `setUserId` |

> **주의**
>
> 이메일, 전화번호, 이름, 주문번호, 원문 회원 ID처럼 개인을 직접 식별할 수 있는 값은 User Property로 보내지 않습니다. 사용자 식별이 필요하면 별도 정책에 맞춘 `setUserId` 적용 여부를 검토합니다.

## 2단계. User Property 이름과 값 설계

Firebase Analytics의 User Property는 앱당 최대 25개까지 사용할 수 있습니다. 이름은 대소문자를 구분하고, Android/iOS에서 다른 이름으로 보내면 서로 다른 속성으로 쌓입니다.

| 속성 이름 | 값 예시 | 설계 기준 |
| --- | --- | --- |
| `membership_level` | `free`, `silver`, `gold` | 회원 등급처럼 값 종류가 제한된 상태 |
| `login_status` | `logged_in`, `logged_out` | 로그인 여부를 이벤트 전반에서 비교할 때 사용 |
| `user_type` | `member`, `guest`, `staff` | 사용자 그룹을 넓게 분류할 때 사용 |
| `app_role` | `buyer`, `seller` | 앱 안의 권한/역할이 분석 기준일 때 사용 |

> **정보**
>
> 이름은 영문자로 시작하고 영문/숫자/밑줄을 사용하는 `snake_case`로 정리합니다. 이름은 24자 이내, 값은 36자 이내로 잡고, 값 종류가 너무 많은 속성은 보고서에서 활용하기 어렵습니다.

## 3단계. Android에서 User ID와 User Property 설정

Android는 사용자 식별값은 `FirebaseAnalytics.setUserId(userId)`, 사용자 상태값은`FirebaseAnalytics.setUserProperty(name, value)`로 나눠 호출합니다. 로그인, 로그아웃, 프로필 갱신처럼 사용자 상태가 바뀌는 시점에 같은 유틸을 호출하도록 묶어 둡니다.

**Android · AppAnalytics.kt 전체 예시**
```kotlin
import com.google.firebase.analytics.FirebaseAnalytics

data class AppUser(
    val userId: String,
    val membershipLevel: String,
    val userType: String
)

class AppAnalytics(
    private val analytics: FirebaseAnalytics
) {
    fun applyUserProperties(user: AppUser?) {
        if (user == null) {
            analytics.setUserId(null)
            analytics.setUserProperty("login_status", "logged_out")
            analytics.setUserProperty("membership_level", null)
            analytics.setUserProperty("user_type", null)
            return
        }

        analytics.setUserId(user.userId)
        analytics.setUserProperty("login_status", "logged_in")
        analytics.setUserProperty("membership_level", user.membershipLevel)
        analytics.setUserProperty("user_type", user.userType)
    }
}
```

**Android · 호출 예시**
```kotlin
val analytics = FirebaseAnalytics.getInstance(context)
val appAnalytics = AppAnalytics(analytics)

appAnalytics.applyUserProperties(
    AppUser(
        userId = "USER_12345",
        membershipLevel = "silver",
        userType = "member"
    )
)
```

> **팁**
>
> 로그아웃 시 이전 사용자 식별값과 상태가 남지 않도록 User ID와 더 이상 유효하지 않은 속성은`null`로 지웁니다.

## 4단계. iOS에서 User ID와 User Property 설정

iOS는 사용자 식별값은 `Analytics.setUserID(_:)`, 사용자 상태값은`Analytics.setUserProperty(_:forName:)`로 나눠 호출합니다. Android와 같은 속성 이름과 같은 값 체계를 사용해야 GA4에서 플랫폼별 데이터를 한 기준으로 비교할 수 있습니다.

**iOS · AppAnalytics.swift 전체 예시**
```swift
import FirebaseAnalytics

struct AppUser {
    let userId: String
    let membershipLevel: String
    let userType: String
}

final class AppAnalytics {
    func applyUserProperties(user: AppUser?) {
        guard let user else {
            Analytics.setUserID(nil)
            Analytics.setUserProperty("logged_out", forName: "login_status")
            Analytics.setUserProperty(nil, forName: "membership_level")
            Analytics.setUserProperty(nil, forName: "user_type")
            return
        }

        Analytics.setUserID(user.userId)
        Analytics.setUserProperty("logged_in", forName: "login_status")
        Analytics.setUserProperty(user.membershipLevel, forName: "membership_level")
        Analytics.setUserProperty(user.userType, forName: "user_type")
    }
}
```

**iOS · 호출 예시**
```swift
let appAnalytics = AppAnalytics()

appAnalytics.applyUserProperties(
    user: AppUser(
        userId: "USER_12345",
        membershipLevel: "silver",
        userType: "member"
    )
)
```

## 5단계. WebView에서 상태 변경을 Native로 전달

WebView 안에서 로그인 상태나 회원 등급이 바뀐다면 Web에서 Firebase Web SDK를 직접 호출하지 말고 Native bridge로 상태 변경을 전달합니다. 최종 호출은 Android/iOS Native SDK의 `setUserId`와`setUserProperty`가 담당합니다.

**Web · firebaseBridge.setUserId / setUserProperty**
```javascript
var firebaseBridge = {
  setUserId: function(userId) {
    var delivered = false;
    var value = userId == null ? null : String(userId);

    if (window.firebaseWebBridge &&
        typeof window.firebaseWebBridge.setUserId === "function") {
      window.firebaseWebBridge.setUserId(value);
      delivered = true;
    }

    if (window.webkit &&
        window.webkit.messageHandlers &&
        window.webkit.messageHandlers.firebaseWebBridge) {
      window.webkit.messageHandlers.firebaseWebBridge.postMessage({
        command: "setUserId",
        userId: value
      });
      delivered = true;
    }

    if (!delivered) {
      console.log("Firebase WebView bridge not found.", "setUserId", value);
    }
  },

  setUserProperty: function(name, value) {
    var delivered = false;

    if (window.firebaseWebBridge &&
        typeof window.firebaseWebBridge.setUserProperty === "function") {
      window.firebaseWebBridge.setUserProperty(name, value == null ? null : String(value));
      delivered = true;
    }

    if (window.webkit &&
        window.webkit.messageHandlers &&
        window.webkit.messageHandlers.firebaseWebBridge) {
      window.webkit.messageHandlers.firebaseWebBridge.postMessage({
        command: "setUserProperty",
        name: name,
        value: value == null ? null : String(value)
      });
      delivered = true;
    }

    if (!delivered) {
      console.log("Firebase WebView bridge not found.", name, value);
    }
  }
};

firebaseBridge.setUserId("USER_12345");
firebaseBridge.setUserProperty("membership_level", "silver");
firebaseBridge.setUserProperty("login_status", "logged_in");
```

**Android bridge · setUserId / setUserProperty**
```java
@JavascriptInterface
public void setUserId(String userId) {
    analytics.setUserId(userId);
}

@JavascriptInterface
public void setUserProperty(String name, String value) {
    if (name == null || name.trim().isEmpty()) {
        return;
    }

    analytics.setUserProperty(name, value);
}
```

**iOS bridge · setUserId / setUserProperty command**
```swift
case "setUserId":
    let rawUserId = payload["userId"]
    let userId = rawUserId is NSNull ? nil : rawUserId.map { String(describing: $0) }
    Analytics.setUserID(userId)

case "setUserProperty":
    guard let name = payload["name"] as? String, !name.isEmpty else {
        return
    }

    let rawValue = payload["value"]
    let value = rawValue is NSNull ? nil : rawValue.map { String(describing: $0) }
    Analytics.setUserProperty(value, forName: name)
```

> **정보**
>
> WebView 이벤트 연동 코드가 이미 있다면 같은 bridge에 `setUserId`와 `setUserProperty`명령만 추가하면 됩니다. 이벤트 전송은 `logEvent`, 사용자 식별은 `setUserId`, 사용자 상태 설정은 `setUserProperty`로 역할을 분리합니다.

## 6단계. GA4 사용자 범위 맞춤 측정기준 등록

User Property를 보고서에서 분석 축으로 쓰려면 GA4에서 사용자 범위 맞춤 측정기준을 등록합니다. 이미 앱 코드에서 보낸 User Property 이름과 GA4 UI의 사용자 속성 값을 정확히 맞춥니다.

**GA4 UI 등록 경로**
```text
관리 > 데이터 표시 > 맞춤 정의 > 맞춤 측정기준 만들기

범위: 사용자
측정기준 이름: membership_level
사용자 속성: membership_level
```

![GA4 맞춤 정의 화면에서 새 맞춤 측정기준 패널을 열고 범위를 사용자로 선택한 실제 화면.](/wiki-assets/playbook/how-to-set-firebase-user-properties/01-user-scoped-custom-definition.png)

> **화면 1.** 범위를 사용자로 선택하고 앱 코드의 User Property 이름을 입력합니다.

> **주의**
>
> 맞춤 측정기준은 등록 이후 들어온 데이터부터 보고서에서 사용할 수 있습니다. 등록 전 데이터에는 소급 적용되지 않으므로, 등록 후 앱에서 User Property와 이벤트를 다시 발생시켜 확인합니다.

## 7단계. DebugView에서 User Property 확인

개발 검증은 DebugView에서 먼저 진행합니다. 디버그 모드를 켠 뒤 앱에서 User Property를 설정하고 이벤트를 한 번 발생시키면, DebugView의 현재 적용된 사용자 속성 영역에서 값을 확인할 수 있습니다.

**Android · DebugView 모드**
```bash
adb shell setprop debug.firebase.analytics.app <application_id>
```

**iOS · Xcode Scheme Run Arguments**
```text
-FIRDebugEnabled
```

![GA4 DebugView 실제 화면. 현재 적용된 사용자 속성 영역에 login_status, membership_level, user_type 값이 표시되어 있다.](/wiki-assets/playbook/how-to-set-firebase-user-properties/02-debugview-user-properties.png)

> **화면 2.** DebugView에서 이벤트 타임라인과 현재 적용된 User Property 값을 같이 확인합니다.

> **완료**
>
> DebugView에서 `membership_level`, `login_status`, `user_type` 값이 보이면 앱에서 User Property가 Firebase Analytics로 정상 전달된 상태입니다.

## 참고 링크

- [Firebase Analytics User Properties(Android)](https://firebase.google.com/docs/analytics/android/user-properties)
- [Firebase Analytics User Properties(iOS)](https://firebase.google.com/docs/analytics/ios/user-properties)
- [Firebase Analytics User ID 설정](https://firebase.google.com/docs/analytics/userid)
- [Android setUserProperty 레퍼런스](https://firebase.google.com/docs/reference/kotlin/com/google/firebase/analytics/FirebaseAnalytics#setuserproperty)
- [iOS setUserProperty 레퍼런스](https://firebase.google.com/docs/reference/swift/firebaseanalytics/api/reference/Classes/Analytics#setuserproperty_forname)
- [GA4 사용자 범위 맞춤 측정기준 만들기](https://support.google.com/analytics/answer/14239618)
- [Firebase 이벤트 전송](/wiki/playbook/firebase-checklist/how-to-send-firebase-events)
- [Firebase 연동 검증](/wiki/playbook/firebase-checklist/how-to-verify-firebase-integration)

## 자주 묻는 질문

### 이벤트 파라미터와 User Property에 같은 값을 둘 다 보내도 되나요?

분석 목적이 다르면 둘 다 보낼 수 있습니다. 특정 행동 순간의 상세값이면 이벤트 파라미터, 이후 여러 이벤트에 공통으로 붙여 비교할 사용자 상태값이면 User Property로 둡니다.

### User Property 값은 언제 설정해야 하나요?

앱 시작 후 사용자 상태를 알게 된 시점, 로그인 성공 시점, 프로필 갱신 시점, 로그아웃 시점에 설정합니다. 값이 바뀌지 않았는데 모든 화면마다 반복 호출할 필요는 없습니다.

### User ID를 User Property로 보내도 되나요?

보내지 않습니다. 사용자 식별 목적은 `setUserId`를 별도로 검토하고, User Property에는 회원 등급이나 로그인 상태처럼 분석 분류에 쓰는 비식별 상태값만 둡니다.

## Navigation

- [전체 플레이북 Markdown sitemap](/wiki/playbook/sitemap.md)

### Firebase

- [Firebase](/wiki/playbook/firebase-checklist)
- [Firebase 프로젝트·앱 등록](/wiki/playbook/firebase-checklist/how-to-create-firebase-app)
- [Firebase SDK 초기화](/wiki/playbook/firebase-checklist/how-to-initialize-firebase-sdk)
- [Firebase WebView 이벤트 연동](/wiki/playbook/firebase-checklist/how-to-connect-firebase-webview-events)
- [Firebase 이벤트 전송](/wiki/playbook/firebase-checklist/how-to-send-firebase-events)
- [Firebase User ID·User Property 설정](/wiki/playbook/firebase-checklist/how-to-set-firebase-user-properties) (현재 문서)
- [Firebase 연동 검증](/wiki/playbook/firebase-checklist/how-to-verify-firebase-integration)
