소셜 로그인(Google / Apple / Kakao / Naver)을 모두 구현한 뒤,
다음으로 고민해야 할 것은 **“로그인 이후 사용자를 어떻게 서비스에 진입시킬 것인가”**이다.
단순히 로그인에 성공했다고 해서 바로 서비스를 사용하게 만드는 것이 항상 최선은 아니다.
대부분의 서비스는 로그인 이후 최소한의 사용자 프로필 정보를 요구한다.
이 글에서는 Firebase Auth 기반 소셜 로그인 이후, 최초 1회만 프로필 작성 화면을 노출하는 온보딩 로직을 어떻게 설계했는지 정리한다.
1. 문제 정의
현재 앱의 상태는 다음과 같다.
- Firebase Auth로 소셜 로그인 완료 가능
- uid 발급 및 인증 상태 관리 가능
- 아직 서비스 레벨의 “회원 프로필”은 존재하지 않음
이 상태에서 발생하는 질문은 하나다.
“로그인이 끝난 사용자를 바로 Home으로 보내도 되는가?”
대부분의 경우 답은 NO다.
- 사용자 이름이 없다
- 프로필 이미지가 없다
- 서비스 내부에서 사용자를 표현할 수 있는 정보가 없다
그래서 로그인(Auth) 과 프로필(Profile) 을 분리한 설계가 필요하다.
2. 설계 목표
이번 온보딩 로직의 목표는 다음과 같다.
- 소셜 로그인 성공 = 인증 완료
- 인증 완료 후, 최초 1회만 프로필 작성 요구
- 이미 프로필이 존재하면 다시 묻지 않음
- 프로필 정보는 Auth가 아닌 서비스 레벨 데이터로 관리
즉,
Auth는 “누구인지 증명”만 책임지고,
Profile은 “서비스에서 누구로 보일지”를 책임진다
3. 전체 흐름 요약
전체 앱 진입 흐름은 아래와 같다.
앱 실행
↓
Firebase Auth 상태 확인
↓
로그인 안 됨 → Login 화면
↓
로그인 성공
↓
HomeViewController 진입
↓
프로필 존재 여부 확인
├─ 없음 → 프로필 작성 화면 표시
└─ 있음 → Home 정상 사용
중요한 점은 **“프로필 작성 화면이 별도의 진입 화면이 아니라, Home 위에서 조건부로 노출된다”**는 것이다.
이 방식은 UX 측면에서도 자연스럽고, 구조적으로도 단순하다.
4. AuthViewModel의 책임
이 구조에서 가장 중요한 설계 포인트는 다음 질문이다.
“프로필 작성 여부를 누가 판단해야 하는가?”
정답은 ViewController가 아니라 AuthViewModel이다.
이유
- Auth 상태는 전역 상태다
- 프로필 유무는 “앱 진입 조건”이다
- Home뿐 아니라, 다른 화면에서도 동일한 판단이 필요해질 수 있다
따라서 AuthViewModel은 다음과 같은 상태를 관리한다.
enum AppEntryState {
case unauthenticated
case needsProfileSetup
case authenticated
}
AuthViewModel은:
- Firebase Auth 상태 변경을 감지하고
- currentUser가 존재하면
- Firestore에 프로필 문서가 존재하는지 확인하여
- 앱의 진입 상태를 결정한다
5. 프로필 존재 여부 판단 기준
프로필 작성 여부를 판단하는 기준은 명확하다.
❌ 사용하지 않는 기준
- Firebase Auth의 displayName
- Firebase Auth의 photoURL
이 값들은 인증 계층의 정보이며,
서비스 로직의 프로필로 사용하기에는 부적절하다.
✅ 사용 기준 (권장)
Firestore
/users/{uid} 문서 존재 여부
- 문서 없음 → 프로필 미작성
- 문서 있음 → 프로필 작성 완료
이 방식은:
- 단순하고
- 명확하며
- 확장성이 좋다
6. Firebase 데이터 구조 설계
6-1. Firebase Storage (프로필 이미지)
이미지 원본은 Storage에 저장한다.
profile-images/
└─ {uid}/
└─ profile.jpg (또는 uuid 기반 파일명)
Storage의 역할은 오직 하나다.
- 바이너리 이미지 저장
6-2. Firestore (프로필 메타데이터)
서비스 로직에서 사용하는 프로필 정보는 Firestore에 저장한다.
users/
└─ {uid}
- username: String
- profileImagePath: String
- createdAt: Timestamp
Firestore의 역할은:
- 빠른 조회
- 서비스 로직에서 필요한 데이터 제공
- Auth와 분리된 회원 정보 관리
👉 Storage에는 절대 닉네임 같은 데이터를 저장하지 않는다.
7. 프로필 작성 UX 설계
프로필 작성 화면은 다음 조건을 만족한다.
- HomeViewController 위에 표시
- Sheet 또는 FullScreenCover 형태
- 입력 항목은 최소화
- 프로필 이미지 (선택)
- Username (필수)
중요한 UX 원칙은 이거다.
“첫 진입에서 사용자를 귀찮게 하지 말 것”
이미지는 선택 사항으로 두고,
닉네임만으로도 프로필 생성을 허용하는 것이 초기 온보딩에 유리하다.
8. 회원 탈퇴와의 연결성
이 설계는 이후 회원 탈퇴 로직과 자연스럽게 연결된다.
- Auth 삭제 → 인증 계정 제거
- Firestore users/{uid} 삭제 → 프로필 정보 제거
- Storage 이미지 삭제 → 리소스 정리
즉, 프로필을 별도 데이터로 관리하기 때문에
탈퇴 로직 역시 명확한 단계로 확장 가능하다.
9. 이 구조의 장점 정리
- Auth / Profile 책임 분리
- 로그인과 서비스 준비 상태를 명확히 구분
- 최초 1회 온보딩 UX 구현 가능
- 이후 기능 확장(설정 변경, 프로필 수정)에 유리
- 실무에서 사용하는 패턴과 동일
10. 마무리
소셜 로그인 구현은 끝이 아니라 시작이다.
진짜 중요한 것은 **“로그인한 사용자를 서비스에 어떻게 안착시키느냐”**다.
이번 설계의 핵심은 단순하다.
로그인은 인증이고,
프로필은 서비스다.
이 둘을 분리해서 설계하면,
온보딩·탈퇴·권한·확장 모든 부분이 자연스럽게 연결된다.
'PulseBoard > Auth' 카테고리의 다른 글
| Firebase Functions로 카카오/네이버 소셜 로그인 Custom Token 발급하기 (0) | 2025.12.31 |
|---|