Search
📚

EP20. Flutter UserService 구현

생성일
2024/06/13 12:50
마지막 업데이트
2024/06/30

EP20. UserService 구현

위 강의에서 패키지에 AuthService를 구현하고 로그인 등 인증/유저에 관련된 기능을 구현했습니다. 패키지에는 유저에 관련된 최소한의 정보만 갖고 있도록 구현했습니다. (패키지를 활용해 어떤 서비스를 구현할지 알 수 없으므로.)
따라서 서비스 수준에서 유저 관련 기능을 구현할 때 패키지의 AuthService를 직접 접근하지 않고 서비스에서 UserService를 구현하고 UserSerivce 내에서 패키지의 AuthService를 활용하는 것이 바람직 합니다.
이번 강의에서는 서비스 수준에서의 UserService를 구현합니다.

1. UserService 구현

패키지 수준의 FPUserService외에 서비스에서 사용할 UserService를 구현합니다.
샘플앱 lib/services 하위에 user_service.dart파일을 추가합니다.
class UserService { // API 클라이언트 인스턴스를 생성하여 사용자 API 엔드포인트 설정 ApiClient apiClient = ApiClient('https://dthvcgffzopawocgahnr.supabase.co/functions/v1/api/users'); FPAuthService authService = FPAuthService(); // 현재 로그인한 사용자 정보를 가져오는 메서드 FPUser? getCurrentUser() { return authService.getCurrentUser(); } Stream<FPUser?> getUserStream() { return authService.getUserStream(); } bool isSignedIn() { return authService.isSignedIn(); } Future<void> signOut() async { await deleteFCMToken(fcmToken: "TODO: FCM 토큰을 가져오는 코드를 작성하세요."); return authService.signOut(); } // FCM 토큰을 삽입 또는 업데이트하는 메서드 Future<void> upsertFCMToken({required String fcmToken}) async { return apiClient.post<EmptyResult>('/v1/fcmToken', {'fcmToken': fcmToken}, (json) => EmptyResult.fromJson(json)) .then((value) => print(value)) // 성공 응답을 출력 .catchError((error) => print(error)); // 에러를 출력 } // FCM 토큰을 삭제하는 메서드 Future<void> deleteFCMToken({required String fcmToken}) async { return apiClient.delete<EmptyResult>('/v1/fcmToken', {'fcmToken': fcmToken}, (json) => EmptyResult.fromJson(json)) .then((value) => print(value)) // 성공 응답을 출력 .catchError((error) => print(error)); // 에러를 출력 } }
Dart
복사
현재 HomeView에서 API를 호출하는 로직을 가져옵니다.
패키지의 AuthService가 담당하는 역할을 서비스에 맞게 변경하여 사용합니다.

3. HomeModel 변경

class HomeModel { final UserService userService; HomeModel(this.userService); Future<void> signOut() async { return await userService.signOut(); } FPUser? user() { return userService.getCurrentUser(); } }
Dart
복사
패키지의 AuthService를 서비스의 UserService로 대체합니다.

4. HomeViewModel 변경

class HomeViewModel extends ChangeNotifier { final HomeModel _model; HomeViewModel() : _model = HomeModel(UserService()); String userID() { return _model.user()?.id ?? '-'; } Future<void> signOut() async { return await _model.signOut(); } }
Dart
복사
HomeModel 생성자로 전달하던 AuthService를 UserService로 변경합니다.

5. HomeView 코드 정리

lib/views/home/home_view.dart
class HomeView extends StatelessWidget { HomeView({super.key}); Widget build(BuildContext context) { // HomeViewModel을 Provider를 통해 가져옴 var viewModel = Provider.of<HomeViewModel>(context); return Scaffold( appBar: AppBar( title: Text('홈 화면'), ), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // 로그인한 유저 ID를 표시하는 텍스트 위젯 Text( '로그인한 유저 ID: ${viewModel.userID()}', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), textAlign: TextAlign.center, ), ElevatedButton( onPressed: () { // 로그아웃 버튼을 눌렀을 때의 동작 viewModel.signOut(); }, child: Text('로그아웃'), ), ], ), ), ); } }
Dart
복사
API호출 로직을 UserService로 위임했으니 HomeView에서 더 이상 불필요한 코드를 제거합니다.

5. RootModel 변경

class RootModel { final UserService userService; RootModel(this.userService); Stream<FPUser?> getUserStream() { return userService.getUserStream(); } bool isSignedIn() { return userService.isSignedIn(); } }
Dart
복사
AuthService를 UserService로 대체합니다.

6. RootViewModel 변경

class RootViewModel extends ChangeNotifier { final RootModel _model; RootViewModel() : _model = RootModel(UserService()); Stream<FPUser?> getUserStream() { return _model.getUserStream(); } bool isSignedIn() { return _model.isSignedIn(); } }
Dart
복사
RootModel 생성자로 전달하던 AuthService를 UserService로 변경합니다.

강의 코드

9
pull