키즈_프로젝트

3. 로그인 화면 필수 요소들 - firebase 유효성검사 추가

깡 딱 2024. 10. 27. 11:23
728x90

 

준비 , 파이어베이스 다운로드

2번까지의 인풋필드를 만들었으면 이제 유효성 검사를 추가해야된다.

https://game-chanda.tistory.com/157

 

2. 로그인 화면 필수 요소들 - 인풋필드 만들기 ( Controller,FocusNode,initState,dispose )

시작전 요약 TextEditingController()역할: 사용자가 입력한 데이터를 저장하고 관리하는 역할을 합니다.FocusNode()역할: 특정 입력 필드에 포커스를 제어하는 역할을 합니다. 즉, 현재 어떤

game-chanda.tistory.com

 

 

우리는 로그인 버튼을 눌렀을때 

인풋필드에 있는 내용들 즉 우리의 데이터가 전송 되어서 이게 정확한 데이터가 전달됬는지

확인 할거잖아요?

 

그러면 로그인 버튼에 어떠한 메서드를 만들어야겠죠?

 

 

그전에 서버와 연동 되기 때문에

https://firebase.google.com/?hl=ko

 

Firebase | Google's Mobile and Web App Development Platform

개발자가 사용자가 좋아할 만한 앱과 게임을 빌드하도록 지원하는 Google의 모바일 및 웹 앱 개발 플랫폼인 Firebase에 대해 알아보세요.

firebase.google.com

 

와 연동을 하고 시작하셔야됩니다

이글에서는 다운방법은 다루지 않겠습니다.

 

 

먼저 로그인 버튼을 눌렀을때 메시지와 빨간색컬러로 뜨기전에 2번 블로그를 보고 오는것을 추천한다.

 

여기까지 준비가 되어있다면 

 


1. 파이어베이스 로그인 오류 메서드 만들기

 

에러 메시지가 뜰 string 텍스트 변수를 하나 선언해준다.

String errorMessage = '';

 

 

그런다음 우리는 

 

Future<UserCredential?> signIn(String email, String password) async {
    _setLoading(true); // 로딩 시작
}

 

Future: 이 함수는 비동기적으로 실행되며, 결과를 나중에 반환합니다. 즉, 즉시 결과를 제공하지 않고, 나중에 결과를 받을 수 있는 약속(Promise)과 같은 개념입니다.
UserCredential?: 이 함수가 반환하는 값의 타입입니다. 여기서 UserCredential은 로그인 성공 시 사용자 정보를 포함하는 객체입니다. ?는 이 값이 null일 수 있음을 의미합니다. 즉, 로그인 실패 시 null을 반환할 수 있습니다.

 

함수 이름을 적어주고 우리의 인풋필드는 이메일 적는곳 비밀번호적는곳 두개니까 텍스트를 저장할 String 함수의 email,password를 만들어줍니다.

 

로그인버튼을 눌렀을때 로딩이 시작 되어야되기 때문에 1번 블로그에 적은 로딩 메서드에 true를 넣어줍니다.

아직 서버에서 처리가 끝나지 않았을때 로딩이 뜨게 만들어야 되기때문에!

 

https://game-chanda.tistory.com/156

 

1. 로그인 화면 필수 요소들 - 로딩바 만들기 CircularProgressIndicator()

CircularProgressIndicator() 설명일단 두가지 주요 형태비결정형Indeterminate: 진행 상황을 알 수 없는 경우에 사용 (기본적으로 사용). 보통 로딩바할때 사용CircularProgressIndicator(); 결정형Determinate: 진행

game-chanda.tistory.com

 


2. 파이어베이스 로그인 오류 메서드 만들기 - 예외처리 ( 오류잡기 , 로딩 )

 

우리는 그후 예외 처리를 알아야되는데 

만약 사용자가 로그인을 성공했을때, 실패했을때 , 오류가 났을때 상황을 적어 놔야하지 않습니까?

그럴때 적는걸 try catch 문 이라고 합니다.

try {
 //Firebase에서 제공하는 메서드로, 사용자의 이메일과 비밀번호를 사용하여 로그인 시도합니다.
  final UserCredential userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword(
    email: email.trim(), // 입력된 이메일에서 앞뒤 공백을 제거하여 깔끔한 형식으로 만듭니다
    password: password.trim(),
  );
  return userCredential; //로그인 성공 시 반환되는 사용자 인증 정보를 담는 변수입니다.
 
}

 

코드에 대한 내용은 주석에 달아 놨습니다.

 

일반적으로 우리는 파이어베이스에서 사용하는 예외처리를 이용해야됩니다

Firebase Authentication에서 발생할 수 있는 예외를 처리하는 부분입니다.

파이어베이스에서 제공하는 오류코드를 이용해 

https://firebase.google.com/docs/auth/flutter/errors?hl=ko

 

오류 처리  |  Firebase 문서

Google I/O 2022에서 Firebase의 새로운 기능을 확인하세요. 자세히 알아보기 이 페이지는 Cloud Translation API를 통해 번역되었습니다. 의견 보내기 오류 처리 컬렉션을 사용해 정리하기 내 환경설정을 기

firebase.google.com

on FirebaseAuthException catch (e) {
  switch (e.code) {
    case 'invalid-email':
      errorMessage = '유효하지 않은 이메일입니다.';
      _emailborderColor = Color(0xFFFF3333);
      break;
    case 'user-disabled':
      errorMessage = '계정이 비활성화 되었습니다.';
      _emailborderColor = Color(0xFFFF3333);
      _passwordBorderColor = Color(0xFFFF3333);
      break;
    case 'user-not-found':
      errorMessage = '사용자를 찾을 수 없습니다.';
      _emailborderColor = Color(0xFFFF3333);
      _passwordBorderColor = Color(0xFFFF3333);
      break;
    case 'wrong-password':
      errorMessage = '잘못된 비밀번호입니다.';
      _passwordBorderColor = Color(0xFFFF3333);
      break;
    case 'missing-password':
      errorMessage = '비밀번호를 입력해야 합니다.';
      _passwordBorderColor = Color(0xFFFF3333);
      break;
    case 'weak-password':
      errorMessage = '비밀번호는 6자 이상이어야 합니다.';
      _passwordBorderColor = Color(0xFFFF3333);
      break;
    case 'invalid-credential':
      errorMessage = '인증 자격 증명이 잘못되었습니다.';
      _emailborderColor = Color(0xFFFF3333);
      _passwordBorderColor = Color(0xFFFF3333);
      break;
    case 'operation-not-allowed':
      errorMessage = '해당 작업이 허용되지 않습니다.';
      _emailborderColor = Color(0xFFFF3333);
      _passwordBorderColor = Color(0xFFFF3333);
      break;
    default:
      errorMessage = '알 수 없는 오류가 발생했습니다.';
      _emailborderColor = Color(0xFFFF3333);
      _passwordBorderColor = Color(0xFFFF3333);
  }
        return null;
    } catch (e) {
      print('로그인 도중 예상치 못한 오류가 발생했습니다: $e');
      return null;
    }

 

오류 코드마다 오류메시지와 인풋필드의 색이 변하게 만들어줍니다.

인풋필드의 색이 변하는건 앞서 말했지만 2번에 자세하게 다뤄 놨습니다.

 

또한 파이어베이스 오류 말고도 일반 오류가 나올 수도 있기 때문에 catch문으로 어떤오류가 발생하는지 

print문으로 적어놨습니다.

 

그후 

finally {
  _setLoading(false); // 로딩 종료
}

 

finally: try 블록에서 예외가 발생하든 발생하지 않든 항상 실행되는 블록입니다. 예외가 발생한 경우 catch 블록이 실행된 후, 마지막에 finally 블록이 실행됩니다.

 

_setLoading(false);: 이 코드는 로딩 상태를 종료하는 역할을 합니다. 예를 들어, 사용자가 로그인 시도를 할 때 로딩 스피너나 진행 표시기를 표시하고, 작업이 끝난 후 이를 숨기는 데 사용될 수 있습니다.


메서드 UI에 전달

위 코드를 전부다 만들었다면

저희가 만든 signInWithErrorCodes 이 코드를 자신의 ui 버튼에  onpressed 에 넣어줍니다

여기서 조심해야될점은 저희가 1번 블로그에서 만들었던 컨트롤러를 넣어줘야됩니다.

그래야 text가 잘 전달 되겠죠? 

Container(
  height: 48,
  width: 428,
  child: MaterialButton(
    onPressed: () async {
      UserCredential? user =
      await signInWithErrorCodes(  //여기
          _textController.text,
          _textController2.text);
      if (user != null) {
        print("Login Successful");
        Navigator.push(
          context,
          MaterialPageRoute(builder: (context) => Home_Screen()), // BottomBar로 이동
        );
      } else {
        print("Login Failed");
      }
    },
    color: Color(0xFF4B0FFF),
    shape: RoundedRectangleBorder(
      borderRadius: BorderRadius.circular(8),
    ),
    child: Container(
      width: 51,
      height: 20,
      child: Text(
        textAlign: TextAlign.center,
        '로그인',
        style: TextStyle(
          color: Colors.white,
          fontFamily: 'Pretendard',
          fontWeight: FontWeight.w700,
          height: 1.0,
          letterSpacing: -0.5,
          fontSize: 20,
        ),
      ),
    ),
  ),
),

 

 

 

 

 


메서드 코드 및 오류발생

메서드 전체를 보면 이렇습니다!

Future<UserCredential?> signInWithErrorCodes(String email, String password) async {
  _setLoading(true); // 로딩 시작

  try {
    final UserCredential userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword(
      email: email.trim(),
      password: password.trim(),
    );
    return userCredential;
  } on FirebaseAuthException catch (e) {
    switch (e.code) {
      case 'invalid-email':
        errorMessage = '유효하지 않은 이메일입니다.';
        _emailborderColor = Color(0xFFFF3333);
        break;
      case 'user-disabled':
        errorMessage = '계정이 비활성화 되었습니다.';
        _emailborderColor = Color(0xFFFF3333);
        _passwordBorderColor = Color(0xFFFF3333);
        break;
      case 'user-not-found':
        errorMessage = '사용자를 찾을 수 없습니다.';
        _emailborderColor = Color(0xFFFF3333);
        _passwordBorderColor = Color(0xFFFF3333);
        break;
      case 'wrong-password':
        errorMessage = '잘못된 비밀번호입니다.';
        _passwordBorderColor = Color(0xFFFF3333);
        break;
      case 'missing-password':
        errorMessage = '비밀번호를 입력해야 합니다.';
        _passwordBorderColor = Color(0xFFFF3333);
        break;
      case 'weak-password':
        errorMessage = '비밀번호는 6자 이상이어야 합니다.';
        _passwordBorderColor = Color(0xFFFF3333);
        break;
      case 'invalid-credential':
        errorMessage = '인증 자격 증명이 잘못되었습니다.';
        _emailborderColor = Color(0xFFFF3333);
        _passwordBorderColor = Color(0xFFFF3333);
        break;
      case 'operation-not-allowed':
        errorMessage = '해당 작업이 허용되지 않습니다.';
        _emailborderColor = Color(0xFFFF3333);
        _passwordBorderColor = Color(0xFFFF3333);
        break;
      default:
        errorMessage = '알 수 없는 오류가 발생했습니다.';
        _emailborderColor = Color(0xFFFF3333);
        _passwordBorderColor = Color(0xFFFF3333);
    }
    return null;
  } catch (e) {
    print('로그인 도중 예상치 못한 오류가 발생했습니다: $e');
    return null;
  } finally {
    _setLoading(false); // 로딩 종료
  }
}

 

 

만약  에러 메시지가 크롬에서 뜨지도 않는다면  파이어베이스와 똑바로 연결이 되지않았습니다.

 

방법으로는 1번 연결하기 귀찮다. 파이어베이스 연결이 똑바로 안되어서

오류 코드가 안되기 때문에

이 코드를 이용하시길 바랍니다.

 

2번 파이어베이스를 다시 다운받아본다. 

Future<UserCredential?> signIn(String email, String password) async {
  try {
    final UserCredential userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword(
      email: email.trim(),
      password: password.trim(),


    );
    return userCredential;
  } on FirebaseAuthException catch (e) {
    if (e.code == 'unknown') {
      if ((e.message ?? '').contains(
          'An unknown error occurred: FirebaseError: Firebase: The email address is badly formatted. (auth/invalid-email)')) {
        errorMessage = '이메일 형식이 상태가 안좋네요';
        _emailborderColor = Color(0xFFFF3333);
        print('이메일 형식이 상태가 안좋네요');
      } else if ((e.message ?? '').contains(
          'An unknown error occurred: FirebaseError: Firebase: A non-empty password must be provided (auth/missing-password).')) {
        errorMessage = '비밀번호 상태가 안좋아요';
        _passwordBorderColor = Color(0xFFFF3333);
        print('비밀번호 상태가 안좋아요');
      } else if ((e.message ?? '').contains(
          'An unknown error occurred: FirebaseError: Firebase: Password should be at least 6 characters (auth/weak-password)')) {
        errorMessage = '암호는 6자 이상이어야 합니다';
        _passwordBorderColor = Color(0xFFFF3333);
        print('암호는 6자 이상이어야 합니다');
      } else if ((e.message ?? '').contains(
          'An unknown error occurred: FirebaseError: Firebase: The supplied auth credential is incorrect, malformed or has expired. (auth/invalid-credential)')) {
        errorMessage = '제공된 인증 자격 증명이 잘못되었거나 형식이 잘못되었습니다';
        _emailborderColor = Color(0xFFFF3333);
        _passwordBorderColor = Color(0xFFFF3333);
        print('제공된 인증 자격 증명이 잘못되었거나 형식이 잘못되었습니다');
      } else if ((e.message ?? '').contains(
          'An unknown error occurred: FirebaseError: Firebase: The user account has been disabled by an administrator. (auth/user-disabled)')) {
        errorMessage = '계정이 비활성화 되었습니다.';
        _emailborderColor = Color(0xFFFF3333);
        print('계정이 비활성화 되었습니다.');
      }
      else {
        print('오류 코드: ${e.code}');
        print('오류 메시지: ${e.message}');
      }
    } else {
      if (e.code == 'user-not-found') {
        errorMessage = '사용자를 찾을 수 없습니다';
        print('사용자를 찾을 수 없습니다');
      } else if (e.code == 'wrong-password') {
        errorMessage = '잘못된 비밀번호입니다';
        print('잘못된 비밀번호입니다');
      } else {
        print('오류 코드: ${e.code}');
        print('오류 메시지: ${e.message}');
      }
    }
    setState(() {}); // 상태를 업데이트하여 UI를 다시 그립니다.
    return null;
  } catch (e) {
    print('로그인 도중 예상치 못한 오류가 발생했습니다: $e');
    return null;
  }
}

 

728x90