firebase 연결 Official Docs:
https://firebase.google.com/docs/flutter/setup?hl=ko&platform=ios
firebase_auth Official Docs:
https://firebase.google.com/docs/auth/flutter/start?hl=ko
pub.dev package page
https://pub.dev/packages/firebase_auth
파이어베이스는 공식문서가 아주 친절합니다.
먼저 개발중인 플러터 앱에 Firebase 를 연결 하고 인증서비스를 추가해야합니다.
연결방법은 저기 첫번째 링크에 아주 친절하게 있으니, 연결을 안하신 분들은
연결부터 하고 오시져!
연결하셨다면, firebase_auth 패키지를 다운받아야 합니다.
flutter pub add firebase_auth 로 다운받고 다시 flutter run으로 빌드하시면 됩니다.
빌드가 잘 되었다면, 콘솔로 넘어오시면 이런 화면이 보입니다.


여기 로그인 제공업체에서 어떤 방식으로 인증을 받을지 설정하시면 됩니다.
저는 SMS로 인증만 받고, 인증이 성공하면 입력한 이메일과 전화번호를 Firebase DB에 넘겨줄 예정입니다.
휴대폰번호로 로그인하는 로직이 아닌, 휴대폰 번호로 인증을 완료한 사용자의 이메일과 비밀번호를 넘겨주어, 이메일로 로그인하는 방식을 구현하고자 하였습니다.
추가 이후 전화 탭을 눌러서 보시면,

이렇게 테스트 전화번호를 설정하실 수 있습니다.
테스트 전화번호가 필요한 이유는,
1. 인증 횟수가 무료 계정인 경우 10회로 제한
2. 안드로이드 에뮬레이터는 인증 번호 확인 불가
두가지 이유입니다.
특히 두번째이유가 큰데, 안드로이드 에뮬레이터에
실제 전화번호를 넣고 인증을 진행해도 SMS 인증번호가 오지 않습니다.
따라서 저기있는 테스트 전화번호를 사용하셔야
다음 로직으로 넘어가실 수 있습니다!
(iOS 시뮬레이터는 잘 날아옵니다!)
final AuthService _authService = AuthService();
String _verificationId = '';
bool _codeSent = false;

// SMS 인증번호 발송 및 확인
Future<void> _verifyPhoneNumber() async {
String phoneNumber = _controllers['phone #']!.text;
String numericPhoneNumber = phoneNumber.replaceAll(RegExp(r'[^0-9]'), '');
String formattedPhoneNumber = '+82$numericPhoneNumber';
await _authService.verifyPhoneNumber(
formattedPhoneNumber,
(verificationId, resendToken) {
setState(() {
_verificationId = verificationId;
_codeSent = true;
_startTimer();
});
},
(verificationId) {
Fluttertoast.showToast(msg: 'Time out, please try again');
},
);
}
저는 Firebase_auth 관련 로직들을 다 auth_service.dart로 모아놨습니다.
이 함수의 flow를 보면
1. 전화번호 변환
처음에 그냥 01012345678 로 넘겼더니 SMS 인증 코드가 안날아와서 찾아보니
+82 같이 앞에 국가 전화 코드가 붙어서 +821012345678 처럼 전달해야 SMS로 인증번호가 날아옵니다!
그래서 전화번호를 변환하여 넘겨주었습니다.
인증번호 전송상태 true 로 변경
시간 초과시 time out 메시지 출력
// Firebase 인증 인스턴스를 변수에 할당
final FirebaseAuth _auth = FirebaseAuth.instance;
Future<void> verifyPhoneNumber(
// 회원가입 페이지에서 받을 정보들 설정
String phoneNumber,
Function(String verificationId, int? resendToken) codeSent,
Function(String verificationId) codeAutoRetrievalTimeout,
) async {
try {
//firebase method 활용
await _auth.verifyPhoneNumber(
phoneNumber: phoneNumber,
verificationCompleted: (PhoneAuthCredential credential) async {
},
verificationFailed: (FirebaseAuthException e) {
Fluttertoast.showToast(msg: e.message ?? 'Verification failed');
},
codeSent: codeSent,
codeAutoRetrievalTimeout: codeAutoRetrievalTimeout,
// 인증번호가 유효한 시각 설정
timeout: const Duration(seconds: 120),
);
} catch (e) {
print(e.toString());
Fluttertoast.showToast(msg: 'Error verifying phone number: $e');
}
}
여기서 verificationId은 사용자가 받는 SMS 코드와 쌍을 이루어 PhoneAuthCredential 을 생성합니다.
이렇게 생성된 Credential을 가지고 사용자에 대한 Authentication을 진행합니다.
Future<void> signInWithPhoneNumber(String verificationId, String smsCode,
String email, String password, String lastName, String firstName) async {
try {
PhoneAuthCredential phoneCredential = PhoneAuthProvider.credential(
verificationId: verificationId,
smsCode: smsCode,
);
UserCredential emailUserCredential =
await _auth.createUserWithEmailAndPassword(
email: email,
password: password,
);
await emailUserCredential.user?.linkWithCredential(phoneCredential);
Fluttertoast.showToast(
msg: 'Successfully linked email and phone number!');
// 요부분dm
await _firestore
.collection("Users")
.doc(emailUserCredential.user!.uid)
.set({
'uid': emailUserCredential.user!.uid,
'email': email,
"lastname": lastName,
"firstname": firstName
});
} on FirebaseAuthException catch (e) {
Fluttertoast.showToast(msg: e.message ?? 'Verification failed');
}
}
}
전화인증을 성공하게 되면 받는 phoneCredential 을 확인하게 되면
firebase_auth 의 메서드인 createUserWithEmailAndPassword 를 활용합니다.
이 함수에 이메일과 비밀번호를 넘겨주면 쉽게 회원가입을 처리하실 수 있습니다.
(이메일과 비밀번호는 controller의 text 가 되겠죠?)
콘솔에서도 넘어온 정보를 확인 하실 수 있습니다.

그리고 iOS 시뮬로 돌리면 실제 전화번호로 인증번호가 날아오는 것을 확인하실 수도 있습니다.

이상입니다!