소셜 로그인(Google, Apple, Kakao, Naver)을 Firebase Authentication 기반으로 구현한 뒤,
다음 단계로 반드시 마주하게 되는 질문이 있다.
“로그인이 끝난 사용자를, 서비스에서는 어떤 모델로 표현해야 할까?”
Firebase Auth에는 이미 User 객체가 존재한다.
그렇다면 이 User를 그대로 써도 되는 걸까?
이 글에서는 Firebase Auth의 User와 분리된 서비스 레벨 사용자 모델 PulseUser를 왜, 어떻게 설계했는지를 정리한다.
1. Auth User ≠ 서비스 User
가장 먼저 명확히 해야 할 개념은 이거다.
Firebase Authentication의 User는 ‘인증 객체’이지,
서비스에서 사용하는 사용자 프로필이 아니다.
Firebase Auth의 User는 다음 책임만 가진다.
- 로그인 여부
- uid 발급
- 어떤 provider로 로그인했는지
하지만 서비스에서는 이런 정보가 필요하다.
- 사용자 이름(닉네임)
- 프로필 이미지
- 자기소개
- 설정 정보
이 두 개념을 섞어버리면,
인증 로직과 서비스 로직이 강하게 결합되고 확장성이 급격히 떨어진다.
그래서 Auth 이후에 사용할 “서비스 레벨 사용자 모델”이 필요하다.
2. PulseUser의 역할 정의
PulseUser는 다음 역할만 수행한다.
- 인증이 완료된 사용자의 프로필 정보 표현
- Firestore에 저장되는 사용자 문서 구조 정의
- 로그인 이후 프로필 온보딩 / 사용자 정보 조회에 사용
즉,
Auth는 “누구인지 증명”하고,
PulseUser는 “서비스에서 어떤 사용자로 보일지”를 정의한다.
3. 소셜 로그인 방식이 달라도 User 모델은 하나다
이 앱에서는 총 4가지 소셜 로그인을 사용한다.
- Google / Apple → Firebase에서 직접 제공
- Kakao / Naver → Custom Token을 통한 Firebase Auth 로그인
여기서 흔히 생기는 오해가 있다.
“소셜 로그인 방식마다 user를 다르게 처리해야 하지 않나?”
결론부터 말하면 그럴 필요 없다.
Firebase Auth에 로그인되는 순간:
Auth.auth().currentUser?.uid
- Google / Apple / Kakao / Naver
- 모든 로그인 방식이 동일한 uid 체계로 수렴한다
Kakao/Naver도 서버에서 Custom Token을 만들 때
provider:userId 형태의 uid를 생성했기 때문에,
Auth 이후에는 차이를 전혀 신경 쓸 필요가 없다.
그래서 PulseUser는:
- 소셜 로그인 종류를 모른다
- uid 하나만 신뢰한다
4. PulseUser 구조체 설계
최종적으로 정의한 PulseUser는 다음과 같다.
struct PulseUser: Codable {
let id: String
let username: String
let profileImagePath: String?
let bio: String?
}
id
- Firebase Authentication에서 발급된 uid
- Firestore 문서 ID(/users/{uid})와 동일하게 사용
- 서비스 전반에서 사용자를 식별하는 기준
username
- 서비스에서 표시할 사용자 이름
- 최초 프로필 온보딩 시 필수 입력 값
- 닉네임 중복 허용 여부는 서비스 정책에 따라 결정
profileImagePath
- Firebase Storage에 저장된 프로필 이미지의 경로 문자열
- URL이 아닌 path를 저장하는 이유:
- URL은 만료/변경될 수 있음
- path는 영구적이며 재생성 가능
예:
profile-images/{uid}/profile.jpg
5. Firebase와의 역할 분리
PulseUser는 Firebase와 이렇게 분리되어 사용된다.
Firebase Authentication
- 로그인
- uid 발급
- 인증 상태 관리
Firestore
- PulseUser 저장
- 사용자 프로필 조회
users/{uid}
├─ id
├─ username
├─ profileImagePath
└─ bio
Firebase Storage
- 프로필 이미지 원본 파일 저장
- PulseUser에는 오직 경로만 저장
이 구조의 장점은 명확하다.
- 인증 / 데이터 / 파일 저장 책임이 분리됨
- 나중에 Firebase를 다른 백엔드로 교체해도 모델 영향 최소화
- 테스트와 유지보수 용이
정리
PulseUser 설계의 핵심은 하나다.
“인증과 서비스는 다르다.”
Firebase Auth는 로그인만 책임지고,
서비스는 자체적인 사용자 모델을 가져야 한다.
PulseUser는:
- 소셜 로그인 방식과 무관하고
- Firebase Auth 이후 단계에 집중하며
- Firestore / Storage와 자연스럽게 연결되는
- 서비스 레벨 사용자 모델이다.
이 분리를 명확히 해두면,
로그인 이후의 온보딩, 프로필 수정, 회원 탈퇴까지
모든 흐름이 자연스럽게 확장된다.
'PulseBoard > Profile' 카테고리의 다른 글
| FirebaseProfileImageUploader 설계 — 프로필 이미지를 왜 분리해야 하는가 (0) | 2026.01.05 |
|---|---|
| FirestoreUserRepository 설계 — 사용자 프로필을 안전하게 관리하는 방법 (0) | 2026.01.04 |
| UserRepository 설계 — Firebase 프로필 데이터를 어떻게 다룰 것인가 (1) | 2026.01.03 |
| Firebase 기반 사용자 프로필 관리 전략 — 서버 단일 소스 + 세션 캐시 (0) | 2026.01.03 |
| 소셜 로그인 이후 프로필 작성 온보딩 설계 (Firebase Auth + Firestore + Storage) (1) | 2026.01.01 |