[Flutter]로그아웃 리펙터링 { firebase google auth }

임물렁·2025년 3월 27일

google Auth 리펙터링

목록 보기
1/2

앱 설계도

아키텍처를 적용한 간단한 로그인 기능을 구현했었다.
부족한 부분을 보완하고자 리펙터링 과정을 기록하려 한다.

LogOut

현재 logout 메서드는 Service에서 가져온다.
Repository에서 받아서 ViewModel이 이를 사용한다.

기존 HomeViewModel 코드

class HomeViewModel with ChangeNotifier {
  final LoginRepository _loginRepository;

  HomeViewModel(this._loginRepository);

  UserModel? get user => _loginRepository.user;
  Future<void> signOut() async {
    await _loginRepository.signOut();
  }
}

기존 HomeView 코드 ( 로그아웃버튼 )

FloatingActionButton(
              onPressed: () {
                viewModel.signOut();
                Navigator.of(context).pushReplacement(
                  MaterialPageRoute(
                    builder:
                        (context) => ChangeNotifierProvider(
                          create:
                              (_) => LoginViewModel(
                                context.read<LoginRepository>(),
                              ),
                          child: LoginScreen(),
                        ),
                  ),
                );
              },
              child: Text('로그아웃'),
            ),

기존 코드는 "로그아웃" 버튼을 누르면 Navigator를 통해
LoginScreen으로 이동하는 형식이었다.

하지만 이렇게 되면 "로그아웃 상태" 임을 반영하지 않는다.

선언적 프레임워크에 위배되고, 확장성과 유지보수성을 깰것같다.

그래서 개선해보자

개선 후 HomeViewModel

그냥 login의 상태를 추가했다.

class HomeViewModel with ChangeNotifier {
  final LoginRepository _loginRepository;

  HomeViewModel(this._loginRepository);

  bool _isLoggedIn = true;
  bool get isLoggedIn => _isLoggedIn;

  UserModel? get user => _loginRepository.user;
  Future<void> signOut() async {
    await _loginRepository.signOut();
    _isLoggedIn = false;
    notifyListeners();
  }
}

HomeView에서 상태 확인

  @override
  Widget build(BuildContext context) {
    final viewModel = context.watch<HomeViewModel>();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (!viewModel.isLoggedIn) {
        Navigator.of(context).pushReplacement(
          MaterialPageRoute(
            builder:
                (context) => ChangeNotifierProvider(
                  create:
                      (_) => LoginViewModel(context.read<LoginRepository>()),
                  child: LoginScreen(),
                ),
          ),
        );
      }
    });
    
    ...
    //버튼
                FloatingActionButton(
              onPressed: viewModel.signOut,
              child: Text('로그아웃'),
            ),

ViewModel의 상태를 받아 로그인 페이지를 전환하는 식으로 바꾸었다.

결론

앱상태에 대해서 배웠다고 생각했는데, 아직 부족하다.
조금은 불편하더라도 View의 모든 상태를 ViewModel이 관리하고,
UI는 그 상태를 통해 움직여야 한다고 느꼈다.
즉, UI가 바뀔만한 모든 요소는 ViewModel이 관리해야 한다고 느꼈다.

로그아웃은 상태를 통해 관리하자

profile
마감을 떠올리며 과정을 하나씩 되짚는

0개의 댓글