코딩하는 제리

[Flutter/Project](Instagram Clone) 페이스북 로그인 본문

Flutter/Project_InstaClone(완)

[Flutter/Project](Instagram Clone) 페이스북 로그인

JerryCho 2021. 2. 9. 14:40


developers.facebook.com/docs/facebook-login/android

 

Android - Facebook 로그인 - 문서 - Facebook for Developers

 

developers.facebook.com

새 앱 만들기
연결된 환경 구축
앱 이름
strings.xml 파일 생성
strings.xml 파일 작성
AndroidManifest.xml 파일에 퍼미션 추가
AndroidManifest.xml 파일의 </application> 바로 앞에 붙여넣기
패키지 이름 복사
패키지 이름 붙여넣기 후 기본 액티비티 클래스 이름 추가
키 복사
키 입력

세이브 후

내 앱 -> 앱 선택 -> 제품 -> Facebook 로그인 설정

 

대시보드의 앱 ID와 시크릿 코드 복사 후 파이어베이스에 붙여넣기.

OAuth 리디렉션 URI 복사 후
붙여넣기
firebase_auth_state.dart
lib/utils/simepl_snackbar.dart 파일 생성
페이스북 로그인 버튼 수정


iOS 설정

developers.facebook.com/docs/facebook-login/ios

 

iOS - Facebook 로그인 - 문서 - Facebook for Developers

 

developers.facebook.com


소스코드 및 pubspec.yaml

// models/firebase_auth_state.dart

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_facebook_login/flutter_facebook_login.dart';
import 'package:flutter_project_IJ/utils/simple_snackbar.dart';

class FirebaseAuthState extends ChangeNotifier {
  // 기본값은 로그아웃 상태
  FirebaseAuthStatus _firebaseAuthStatus = FirebaseAuthStatus.signout;
  FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
  FirebaseUser _firebaseUser;

  void watchAuthChange() {
    // onAuthStateChanged를 통해 firebaseUser를 보냄.
    _firebaseAuth.onAuthStateChanged.listen((firebaseUser) {
      if (firebaseUser == null && _firebaseUser == null) {
        return;
      } else if (firebaseUser != _firebaseUser) {
        // 받아온 firebaseUser와 _firebaseUser가 같지 않으면
        // 업데이트.
        _firebaseUser = firebaseUser;
        // 업데이트 후 changeFirebaseAuthStatus() 실행.
        // firebaseAuthStatus 파라미터를 넣지 않았기에
        // else if로 바로 넘어감.
        changeFirebaseAuthStatus();
      }
    });
  }

  // 회원가입
  void registerUser(BuildContext context,
      {@required String email, @required String password}) {
    _firebaseAuth
        .createUserWithEmailAndPassword(
            email: email.trim(), password: password.trim())
        .catchError((error) {
      print(error);
      String _message = "";
      switch (error.code) {
        case "ERROR_WEAK_PASSWORD":
          _message = "패스워드를 확인해주세요.";
          break;
        case "ERROR_INVALID_EMAIL":
          _message = "이메일을 확인해주세요.";
          break;
        case "ERROR_EMAIL_ALREADY_IN_USE":
          _message = "이미 사용중인 이메일입니다.";
          break;
      }
      // 스낵바 출력
      simpleSnackbar(context, _message);
    });
  }

  // 로그인
  void login(BuildContext context,
      {@required String email, @required String password}) {
    _firebaseAuth
        .signInWithEmailAndPassword(
            email: email.trim(), password: password.trim())
        .catchError((error) {
      print(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;
      }
      simpleSnackbar(context, _message);
    });
  }

  // 로그아웃
  void signOut() {
    _firebaseAuthStatus = FirebaseAuthStatus.signout;
    if (_firebaseUser != null) {
      _firebaseUser = null;
      _firebaseAuth.signOut();
    }
    notifyListeners();
  }

  // [] -> 옵션
  void changeFirebaseAuthStatus([FirebaseAuthStatus firebaseAuthStatus]) {
    if (firebaseAuthStatus != null) {
      _firebaseAuthStatus = firebaseAuthStatus;
    } else if (_firebaseUser != null) {
      // 유저 데이터가 있으면 singin
      _firebaseAuthStatus = FirebaseAuthStatus.singin;
    } else {
      _firebaseAuthStatus = FirebaseAuthStatus.signout;
    }
    notifyListeners();
  }

  // 페이스북 로그인
  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 {
    // 토큰을 사용하여 파이어베이스 로그인
    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();
  }

  FirebaseAuthStatus get firebaseAuthStatus => _firebaseAuthStatus;
}

enum FirebaseAuthStatus { signout, progress, singin }
Comments