ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Flutter - 코딩마스터하기|Firebase Firestore 사용하기2
    개발/Flutter 2021. 11. 15. 16:59
    반응형

    how to cancel stream

    해당 stream을 로그아웃시 취소를 해줘야 기존 로그인 유저의 데이터를 변경해도 변경이 안됨. 이작업을 해야함.

    이를 위해서 main.dart에서 signin에 만들었던 부분을 메소드로 만들어 준다. _initUserModel이란 메소드로 만들어 주고 UserModelState userModelState = Provider.of<UserModelState>(context, listen: false); 이렇게 먼저 생성해 준 다음 기존 userNetworkRepository 뒷부분을 userModelState.currentStreamSub = 에 넣어 준다. 그리고 listen의 부분을 userModelState.userModel = userModel; 이렇게 줄여준다. 그러면 userModelState부분에도 currentStreamSub 를 만들어 준다. 우선 상단에 StreamSubscription<UserModel> _currentStreamSub;를 생성 해준다. user_model_state 파일로 가서 우선 변경 할 수 있도록 set currentStreamSub(StreamSubscription<UserModel> currentStreamSub) => _currentStreamSub; 를 생성해준다. 그리고 구독을 해지할 수 있도록   clear() { if (_currentStreamSub != null) { _currentStreamSub.cancel(); } _currentStreamSub = null; _userModel = null; } 를 생성 해주면된다. 그리고 버튼 아무곳에나 Provider.of<UserModelState>(context, listen:false).clear(); 넣고 누른 뒤에 파이어스토어에서 데이터를 변경해도 안바뀌는것을 볼 수 있다.(근데 내껀 왜 변경되지..) 


    main.dart
      void _initUserModel(
          FirebaseAuthState firebaseAuthState, BuildContext context) {
        UserModelState userModelState =
            Provider.of<UserModelState>(context, listen: false);
    
        userModelState.currentStreamSub = userNetworkRepository
            .getUserModelStream(firebaseAuthState.firebasUser.uid)
            .listen((userModel) {
          userModelState.userModel = userModel;
        });
      }
    
      void _clearUserModel(BuildContext context) {
        UserModelState userModelState =
            Provider.of<UserModelState>(context, listen: false);
        userModelState.clear();
      }
    user_model_state.dart
    class UserModelState extends ChangeNotifier {
      UserModel _userModel;
      StreamSubscription<UserModel>
          _currentStreamSub; //유저의 구독권을 갖고있는 부분. 로그아웃시 취소시켜줘야하는부분.
    
      UserModel get userModel => _userModel;
    
      set userModel(UserModel userModel) {
        _userModel = userModel;
        notifyListeners();
      }
    
      set currentStreamSub(StreamSubscription<UserModel> currentStreamSub) =>
          _currentStreamSub;
    
      clear() {
        if (_currentStreamSub != null) {
          _currentStreamSub.cancel();
        }
        _currentStreamSub = null;
        _userModel = null;
      }
    }

    로그인할때 FirebaseUser 생성해주기

    login시에도 register처럼 authResult를 생성해주자.  login 메소드에서 _firebaseAuth로 이메일과 암호를 통해 signIn하는 부분에 AuthResult authResult = await _firebaseAuth 로 해준뒤에 하단에 _firebaseUser = authResult.user; if (_firebaseUser == null) { SnackBar snackBar = SnackBar( content: Text("Please try again later!"), ); Scaffold.of(context).showSnackBar(snackBar); } 를 추가해준다. register와 다르게 else부분은 없이 로그인 되어있는지만 확인하면 된다.


      void login(BuildContext context,
          {@required String email, @required String password}) async {
        changeFirebaseAuthStatus(FirebaseAuthStatus.progress);
        AuthResult authResult = await _firebaseAuth
            .signInWithEmailAndPassword(
                email: email.trim(), password: password.trim())
            .catchError((error) {
          String _message = '';
          switch (error.code) {
            case 'ERROR_INVALID_EMAIL':
              _message = '메일 주소가 유효하지 않습니다.';
              break;
            case 'ERROR_WRONG_PASSWORD':
              _message = '암호가 틀렸습니다.';
              break;
            case 'ERROR_USER_NOT_FOUND':
              _message = '가입하지 않은 아이디입니다.';
              break;
            case 'ERROR_USER_DISABLED':
              _message = '해당유저는 금지되어 있습니다.';
              break;
            case 'ERROR_TOO_MANY_REQUESTS':
              _message = '너무 많이 시도하였습니다. 나중에 다시 시도해주세요.';
              break;
            case 'ERROR_OPERATION_NOT_ALLOWED':
              _message = '허용되지 않았습니다.';
              break;
          }
    
          SnackBar snackBar = SnackBar(
            content: Text(
              _message,
            ),
          );
          Scaffold.of(context).showSnackBar(snackBar);
        });
    
        _firebaseUser = authResult.user;
        if (_firebaseUser == null) {
          SnackBar snackBar = SnackBar(
            content: Text("Please try again later!"),
          );
          Scaffold.of(context).showSnackBar(snackBar);
        }
      }

    null checking

    강의중에 profile_body에서 firesotre에서 username을 불러올때부터 자꾸 null 에러가 났는데 이부분을 수정해 보자. _username 메소드에서 에러가 나는데  이 부분의 수정을 위해서, 상단에 UserModelState userModelState = Provider.of<UserModelState>(context);를 생성 해준다. 그리고 username를 사용하는 부분인 Text안에 if문을 만들어 준다. userModelState == null || userModelState.userModel == null일때 true이면 "" 빈값을 주고 아니면 username을 주면 된다. 실행 해 보면 정상적으로 실행되는 것을 볼 수 있다.


      Widget _username(BuildContext context) {
        UserModelState userModelState = Provider.of<UserModelState>(context);
        return Padding(
          padding: const EdgeInsets.symmetric(
            horizontal: common_gap,
          ),
          child: Text(
            userModelState == null || userModelState.userModel == null
                ? ""
                : userModelState.userModel.username,
            style: TextStyle(
              fontWeight: FontWeight.bold,
            ),
          ),
        );
      }

     


     

    반응형

    댓글

Designed by Tistory.