오늘은 Kotlin을 사용하여 Firebase의 Authentication을 사용하여 로그인 기능을 구현해 본다.
이제까지 Java를 사용해서 몇번 해봤기 때문에 큰 어려움은 없을 것 같다!
오늘은 3가지 유형을 사용한 로그인 기능을 만든다!
1. Email 로그인
2. Google 로그인
3. Facebook 로그인
위 로그인 기능들을 사용하려면 Android Project와 Firebase를 연결해줘야 한다.
'Tools > Firebase'를 클릭한 후
'Authentication > Authenticate using a custom authentication system'을 누른다.
그 후, 1번과 2번을 차례대로 눌러 진행해주면 된다.
이부분은 서치를 조금만 해도 자세히 나와있는 문서들이 많으니 이정도로 패쓰!!
이제 Email 로그인과 Google 로그인을 사용하기 앞서
build.gradle(Module: ) - dependencies 종속 선언을 해준다.
implementation 'com.google.android.gms:play-services-auth:19.0.0'
implementation 'com.google.firebase:firebase-auth-ktx'
연결이 되었으면 'Firebase > Authentication > Sign-in-method'로 간다.
우리가 사용할 이메일/비밀번호 를 ON 하여 사용 설정한다.
사용설정이 완료 되었으니! 이제 안드로이드에서 사용해보장
FirebaseAuth 객체를 선언해준다
( nullable로 잡아 통신이 안되면 NPE가 뜨도록 해준다!)
//nullable한 FirebaseAuth 객체 선언
var auth: FirebaseAuth? = null;
//auth 객체 초기화
auth = FirebaseAuth.getInstance()
'로그인 또는 가입하기' 버튼을 클릭 시 다음 순서로 진행시킬 것이다.
1. 사용자가 입력한 이메일이 Firebase DB에 있는지 확인한다.
2. (있을 경우) : 비밀번호를 대조하여 맞다면 로그인 처리한다.
(없을 경우) : 새롭게 계정을 등록한 후 로그인 처리한다.
Firebase는 유저의 이메일, 비밀번호를 서버 DB와 대조한 뒤 올바르다면 해당 유저를 로그인 상태로 기록한다.
//signUp 함수
auth?.createUserWithEmailAndPassword(emailEditText.text.toString(),passwordEditText.text.toString())
?.addOnCompleteListener { //통신 완료가 된 후 무슨일을 할지
task ->
if(task.isSuccessful){
//정상적으로 이메일과 비번이 전달되어
//새 유저 계정을 생성과 서버db 저장 완료 및 로그인
//즉, 기존에 있는 계정이 아니다!
goMainActivity(task.result?.user)
}
else if (task.exception?.message.isNullOrEmpty()==false){
//예외메세지가 있다면 출력
//에러가 났다거나 서버가 연결이 실패했다거나
Toast.makeText(this,task.exception?.message,Toast.LENGTH_LONG).show()
}
else{
//여기가 실행되는 경우는 이미 db에 해당 이메일과 패스워드가 있는 경우
//그래서 계정 생성이 아닌 로그인 함수로 이동
signIn()
}
}
//signIn 함수
auth?.signInWithEmailAndPassword(emailEditText.text.toString(),passwordEditText.text.toString())
?.addOnCompleteListener { //통신 완료가 된 후 무슨일을 할지
task ->
if(task.isSuccessful){
//로그인 처리를 해주면 됨!
goMainActivity(task.result?.user)
}
else{
// 오류가 난 경우!
Toast.makeText(this,task.exception?.message,Toast.LENGTH_LONG).show()
}
}
auth의 createUserWithEmailAndPassword 함수와 signInWithEmailAndPassword 함수를 실행 시킨 모습이다.
둘의 차이는 주석을 읽어보면 감이 오겠지만 요약하자면 이렇다!
"auth의 create~()... 후 isSuccessful -> DB 저장(계정 생성)이 정상적으로 완료되었을 때
auth의 signin~()... 후 isSuccessful -> 로그인이 정상적으로 완료되었을 때"
GoogleSignInClient 객체를 선언/초기화를 해준다.
//auth 객체 초기화
auth = FirebaseAuth.getInstance()
//GoogleSignInClient 객체 초기화
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) //기본 로그인 방식 사용
.requestIdToken(getString(R.string.default_web_client_id))
//requestIdToken :필수사항이다. 사용자의 식별값(token)을 사용하겠다.
//(App이 구글에게 요청)
.requestEmail()
// 사용자의 이메일을 사용하겠다.(App이 구글에게 요청)
.build()
// 내 앱에서 구글의 계정을 가져다 쓸거니 알고 있어라!
googleSignInClient = GoogleSignIn.getClient(this,gso)
구글로그인 버튼 클릭 시 실행될 googleLogin() 을 만들어 준다.
private fun googleLogin() {
//1. 구글로 로그인을 한다.
val signInIntent = googleSignInClient?.signInIntent
startActivityForResult(signInIntent,1004)
}
startActivityForResult의 결과에 따라서 구글 로그인을 시도 한다.
//startAcivityResult()로 인해 다른 앱/ 액티비티가 실행된 후.
//그 앱/액티비티의 작업이 끝나서 다시 이 액티비티로 돌아왔을 떄 할일
override fun onActivityResult(requestCode:Int, resultCode: Int, data: Intent?){
//Activity.Result_OK : 정상완료
//Activity.Result_CANCEL : 중간에 취소 되었음(실패)
super.onActivityResult(requestCode, resultCode, data)
if(requestCode==1004){
if(resultCode == Activity.RESULT_OK){
//결과 Intent(data 매개변수) 에서 구글로그인 결과 꺼내오기
val result = Auth.GoogleSignInApi.getSignInResultFromIntent(data)!!
//정상적으로 로그인되었다면
if(result.isSuccess){
//우리의 Firebase 서버에 사용자 이메일정보보내기
val account = result.signInAccount
firebaseAuthWithGoogle(account)
}
}
}
}
정상적으로 로그인 시 서버에 사용자 정보를 보내 줄 firebaseAuthWithGoogle()
private fun firebaseAuthWithGoogle(account: GoogleSignInAccount?) {
//구글로부터 로그인된 사용자의 정보(Credentail)을 얻어온다.
val credential = GoogleAuthProvider.getCredential(account?.idToken!!, null)
//그 정보를 사용하여 Firebase의 auth를 실행한다.
auth?.signInWithCredential(credential)
?.addOnCompleteListener { //통신 완료가 된 후 무슨일을 할지
task ->
if (task.isSuccessful) {
// 로그인 처리를 해주면 됨!
goMainActivity(task.result?.user)
} else {
// 오류가 난 경우!
Toast.makeText(this, task.exception?.message, Toast.LENGTH_LONG).show()
}
progressBar.visibility = View.GONE
}
}
firebase auth에 사용자 목록에 올라가지 않는데 이유가 있을까요...?