개발/Flutter

Flutter - 코딩마스터하기|페이스북 로그인

ffuny 2021. 11. 9. 17:29
반응형

페이스북 로그인

일단 pub.dev에서 flutter_facebook_login: ^3.0.0를 설치해 준 후(현재 개발 중단으로 보임, pub get하면 마이그레이션 하라고함 나중에 다른 라이브러리로 해볼것), read me에서 안드로이드 부분의 파란 링크부분을 클릭해서 프로젝트르 생성하거나, 기존의 프로젝트를 선택한다. 그 후 4번의 리소스 및 메니페스트 수정으로 가서 첫번째 것을 복사 해준 뒤에, android - app - src - main - res - values 에 strings.xml을 만들어 주고 resources안에 복사한것을 붙여준다.(같은 경로에 있던 styles.xml 을 복사하고 resources 의 안의 내용을 지운뒤 붙여넣기 해줘도 된다.) 그리고 2번째를 복사해서 AndroidManifest.xml을 열어서 가장 위쪽에 권한을 넣어줬던 부분에 밑에 바로 넣어주면 된다. 마지막 세번째 부분을 복사해서 같은 파일에서 하단의  </application>의 바로 위쪽에 붙여넣어주면 된다. 그리고 5번에는 패키지 이름에는 AndroidManifest.xml 상단에 package=''에 들어있는 부분을 복사해서 넣어주고 기본 액티비티 클래스 이름은 패키지 이름에 .MainActivity를 넣어주면 된다. 6번에서 릴리스 키 해시 생성이 있는데 openssl과 jdk path를 설치와 환경변수로 잡아줌. 여기서 keytool -exportcert -alias androiddebugkey -keystore "C:\Users\USERNAME\.android\debug.keystore" | "PATH_TO_OPENSSL_LIBRARY\bin\openssl" sha1 -binary | "PATH_TO_OPENSSL_LIBRARY\bin\openssl" base64 를 복사하는데 USERNAME과 PATH_TO_OPENSSL_LIBRARY를 경로를 바꿔주면 해시키가 나온다.(안드로이드 스튜디오에서 터미널에서 경로에 android에서 하면 된다.) 나온 해시키를 하단에 키 해시에 넣어주고 저장하면 된다. 이 페이지에서 세팅은 끝이고 파이어베이스 콘솔로 가보자. 페이스북 로그인 설정을 눌러주고 안드로이드를 눌러준다. 다 다음을 눌러주고 설정에 가서 앱id와 앱 secreat를 복사해서 파이어베이스에 페이스북 로그인 사용을 눌러주고 복사한 부분들을 붙여 넣어준다. 그리고 앱 아이디와 시크릿 부분에서 하단에 OAuth 부분을 복사해서 페이스북에 와서 페이스북 로그인 설정으로 가서 유효한 OAuth 리디렉션 URI에 넣어준다. 그리고 안드로이드 스튜디오의 firebase_auth_state로 와서 로그인하는 메소드를 만들어 줄 것이다. 아래와 같이 메소드 2개를 만들어 주면 된다.


  void loginWithFacebook(BuildContext context) async {
    final facebookLogin = FacebookLogin();
    final result = await facebookLogin.logIn(['email']);

    switch(result.status){

      case FacebookLoginStatus.loggedIn:
        _handleFacebookTokenWithFirebase(context, result.accessToken.token);
        break;
      case FacebookLoginStatus.cancelledByUser:
        simpleSnackbar(context, 'User cancel facebook sign in');
        break;
      case FacebookLoginStatus.error:
        simpleSnackbar(context, '페이스북 로그인하는 중에 에러가 발생했습니다.');
        facebookLogin.logOut();
        break;
    }
  }

  void _handleFacebookTokenWithFirebase(BuildContext context, String token) async {
    final AuthCredential credential = FacebookAuthProvider.getCredential(accessToken: token,);
    final AuthResult authResult = await _firebaseAuth.signInWithCredential(credential);
    final FirebaseUser user = authResult.user;
    if(user == null){
      simpleSnackbar(context, '페이스북 로그인이 되지 않았습니다. 다시 시도해주시기 바랍니다.');
    }else{
      _firebaseUser = user;

    }
    notifyListeners();
  }

그리고 sign_up_form과 sign_in_form에 하단의 가입이나 로그인 버튼의 Provider를 그대로 복사해와서 마지막의 메소드를 .loginWithFacebook(context)로 변경해주면 된다. 그리고 실행해서 페이스북 앱을 깔고 개발모드로 가입한 아이디로 로그인을 하면 정상적으로 나오는 것을 알 수 있다.

 

signout(logout) facebook as well

사인아웃 부분을 좀더 개선해보자. 사인아웃을 하더라도 페이스북 자체는 로그아웃이 안됨. 이를 해결해주려함. 일단 final facebookLogin = FacebookLogin(); 부분을 상단으로 올려주자. 클래스 내의 상단에 FacebookLogin _facebookLogin;을 만들어 주고, 기존 부분은 _facebookLogin이 null일때만 값을 받도록 해준다. 그리고 signOut 메소드에서 async를 추가해주고 _firebaseAuth.signOut(); 앞에 await를 추가해준다. 그리고 await _facebookLogin.logOut();으로 로그아웃 해준다. 이때 if문으로 감싸주고 await _facebookLogin.isLoggedIn으로 해줘서 로그인 상태일때만 로그아웃 해주게 한다. 실행해보면 정상적으로 작동하는것을 볼 수 있다.


  void signOut() async {
    _firebaseAuthStatus = FirebaseAuthStatus.signout;
    if (_firebaseUser != null) {
      _firebaseUser = null;
      await _firebaseAuth.signOut();
      if(await _facebookLogin.isLoggedIn){
        await _facebookLogin.logOut();
      }
    }
    notifyListeners();
  }

  void loginWithFacebook(BuildContext context) async {
    if(_facebookLogin == null){

      _facebookLogin = FacebookLogin();
    }
    final result = await _facebookLogin.logIn(['email']);

    switch(result.status){

      case FacebookLoginStatus.loggedIn:
        _handleFacebookTokenWithFirebase(context, result.accessToken.token);
        break;
      case FacebookLoginStatus.cancelledByUser:
        simpleSnackbar(context, 'User cancel facebook sign in');
        break;
      case FacebookLoginStatus.error:
        simpleSnackbar(context, '페이스북 로그인하는 중에 에러가 발생했습니다.');
        _facebookLogin.logOut();
        break;
    }
  }

progress while auth state change

지금은 기본상태가 signout이고, 각 로그아웃,로그인때 progress상태가 없다. 그래서 loginWithFacebook, signOut, login, registerUser 메소드 상단에 changeFirebaseAuthStatus(FirebaseAuthStatus.progress);를 추가해준 뒤 실행해보면 로딩페이지가 나오는 것을 볼 수 있다. 로그아웃은 상태가 너무 빨리 바뀌어서 안보이는것처럼 보인다. 그리고 처음 상태를 progress로 바꾸기 위해서 클래스내의 맨 위의 signout를 progress를 해준다. 하지만 이때 정지 후 다시 실행해보면 무한 로딩인데 처음에 null상태를 주기때문에 이를 해결해 줘야한다. 상단에 bool initiated = false;를 만들어 주고 watchAuthChange메소드에서 if문에 true일때 if(initiates) 를 넣어주고 true에서 changeFirebaseAuthStatus();를 해주고 flase일 때 initiated = true;로 해주면 앱 실행시 로딩바가 나오는 것을 알 수 있다.(간단해서 코드추가x)

추가강의 - 원래는 firebaseUser가 null이 날라왔는데 현재 그 부분이 개선된것으로 보임 그래서 initiated 삭제하고 if문이 있던 부분은 changeFirebaseAuthStatus(); 만 남겨주면됨.

반응형