Notice
Recent Posts
Recent Comments
Link
먼지나는 블로그
kotlin firebase 설정 및 로그인 구현 본문
본인이 파이어베이스를 사용하고자 하는 코틀린 프로젝트의 AndroidManifast.xml 파일에 들어가 package 값을
복사에서 이름에 넣어주면 나머지항목은 그대로 두고 등록버튼 클릭
다음 단계는 나와있는 대로 진행하면 됨
프로젝트 수준의 build.gradle 파일에 나와있는 코드가 입력되어 있는지 확인. 안되어있다면 추가
앱 수준의 bulid.gradle.도 코드를 추가함
우선 이메일/비밀번호를 사용해 로그인기능을 구현해보기로함
앱 수준의 build.gradle에서 implementation 'com.google.firebase:firebase-auth-ktx' 추가
로그인 기능을 따로 추가하기 위한 LoginActivity.kt 파일 생성
Activity 추가시 manifest 추가 필수
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="24dp">
<EditText
android:id="@+id/emailEditText"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/passwordEditText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:inputType="textPassword"
app:layout_constraintTop_toBottomOf="@+id/emailEditText"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>
<Button
android:id="@+id/loginButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="로그인"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/googleLoginBtn" />
<Button
android:id="@+id/signUpButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:text="회원가입"
app:layout_constraintEnd_toStartOf="@+id/loginButton"
app:layout_constraintTop_toBottomOf="@id/googleLoginBtn" />
<com.google.android.gms.common.SignInButton
android:id="@+id/googleLoginBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/passwordEditText"
app:layout_constraintStart_toStartOf="parent"
android:text="구글로그인"
app:layout_constraintEnd_toEndOf="parent"
tools:ignore="MissingConstraints"></com.google.android.gms.common.SignInButton>
</androidx.constraintlayout.widget.ConstraintLayout>
↑activity_login.xml 레이아웃 파일도 같이 생성
package com.example.login
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.common.SignInButton
import com.google.android.gms.common.api.ApiException
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.GoogleAuthProvider
import com.google.firebase.auth.ktx.auth
import com.google.firebase.database.ktx.database
import com.google.firebase.ktx.Firebase
class LoginActivity: AppCompatActivity() {
private lateinit var auth: FirebaseAuth
private lateinit var googleSignInClient: GoogleSignInClient
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
auth = Firebase.auth // = FirebaseAuth.getInstance()
val emailEditText = findViewById<EditText>(R.id.emailEditText)
val passwordEditText = findViewById<EditText>(R.id.passwordEditText)
val loginButton = findViewById<Button>(R.id.loginButton)
val signUpButton = findViewById<Button>(R.id.signUpButton)
loginButton.setOnClickListener{
val email = emailEditText.text.toString()
val password = passwordEditText.text.toString()
auth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
successLogin()
} else {
Toast.makeText(this, "로그인에 실패했습니다. 이메일 또는 비밀번호를 확인해주세요.", Toast.LENGTH_SHORT).show()
}
}
}// ctrl+alt+m refactor > function 안드로이드스튜디오에서 제공하는 기능
emailEditText.addTextChangedListener {
val enable = emailEditText.text.isNotEmpty() && passwordEditText.text.isNotEmpty()
loginButton.isEnabled = enable
signUpButton.isEnabled = enable
}
passwordEditText.addTextChangedListener {
val enable = emailEditText.text.isNotEmpty() && passwordEditText.text.isNotEmpty()
loginButton.isEnabled = enable
signUpButton.isEnabled = enable
}
signUpButton.setOnClickListener {
val email = emailEditText.text.toString()
val password = passwordEditText.text.toString()
auth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
Toast.makeText(this, "회원가입을 성공했습니다. 로그인 버튼을 눌러 로그인해주세요.", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this, "이미 가입한 이메일이거나, 회원가입에 실패했습니다.", Toast.LENGTH_SHORT).show()
}
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
// Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
if (requestCode == GOOGLE_REQUEST_CODE) {
val task = GoogleSignIn.getSignedInAccountFromIntent(data)
try {
// Google Sign In was successful, authenticate with Firebase
val account = task.getResult(ApiException::class.java)!!
Log.d(TAG, "firebaseAuthWithGoogle:" + account.id)
firebaseAuthWithGoogle(account.idToken!!)
} catch (e: ApiException) {
// Google Sign In failed, update UI appropriately
Log.w(TAG, "Google sign in failed", e)
Toast.makeText(this, "로그인 실패", Toast.LENGTH_SHORT).show()
}
}
}
private fun initLoginButton() {
val loginButton = findViewById<Button>(R.id.loginButton)
loginButton.setOnClickListener {
val email = getInputEmail()
val password = getInputPassword()
auth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(this) { task ->
if ( task.isSuccessful ) {
Toast.makeText(this, "로그인에 성공했습니다", Toast.LENGTH_SHORT).show()
successLogin()
// 로그인에 성공했다면 액티비티 종료
} else {
Toast.makeText(this, "로그인에 실패했습니다. 이메일 또는 전화번호를 확인해주세요", Toast.LENGTH_SHORT).show()
}
}
}
}
// 예외처리
private fun initEmailAndPasswordEditText() {
val emailEditText = findViewById<EditText>(R.id.emailEditText)
val passwordEditText = findViewById<EditText>(R.id.passwordEditText)
val loginButton = findViewById<Button>(R.id.loginButton)
val signUpButton = findViewById<Button>(R.id.signUpButton)
emailEditText.addTextChangedListener {
val enable = emailEditText.text.isNotEmpty() && passwordEditText.text.isNotEmpty()
loginButton.isEnabled = enable
signUpButton.isEnabled = enable
}
passwordEditText.addTextChangedListener {
val enable = emailEditText.text.isNotEmpty() && passwordEditText.text.isNotEmpty()
loginButton.isEnabled = enable
signUpButton.isEnabled = enable
}
}
private fun getInputEmail(): String {
return findViewById<EditText>(R.id.emailEditText).text.toString()
}
private fun getInputPassword(): String {
return findViewById<EditText>(R.id.passwordEditText).text.toString()
}
private fun successLogin() {
if (auth.currentUser == null) {
Toast.makeText(this, "로그인에 실패했습니다. 다시 시도해주세요.", Toast.LENGTH_SHORT).show()
return
}
val userId: String = auth.currentUser?.uid.orEmpty() //null이라면 빈값을 넣어줌
val currentUserDb = Firebase.database.reference.child("Users").child(userId)
val user = mutableMapOf<String, Any>()
user["userId"] = userId
currentUserDb.updateChildren(user)
finish()
}
}
LoginActivity.kt 파일 코드
package com.example.login
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
import com.google.firebase.auth.FirebaseAuth
class MainActivity : AppCompatActivity() {
private val auth: FirebaseAuth = FirebaseAuth.getInstance()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onStart() {
super.onStart()
if (auth.currentUser == null) {
startActivity(Intent(this, LoginActivity::class.java))
}
}
}
MainActivity.kt 파일 코드
무사히 이메일과 비밀번호가 파이어베이스에 저장됨.
구글 로그인 기능 추가
더보기
package com.example.login
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.widget.addTextChangedListener
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInClient
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.android.gms.common.SignInButton
import com.google.android.gms.common.api.ApiException
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.GoogleAuthProvider
import com.google.firebase.auth.ktx.auth
import com.google.firebase.database.ktx.database
import com.google.firebase.ktx.Firebase
class LoginActivity: AppCompatActivity() {
private lateinit var auth: FirebaseAuth
private lateinit var googleSignInClient: GoogleSignInClient
val GOOGLE_REQUEST_CODE = 99
val TAG = "googleLogin"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
auth = Firebase.auth // = FirebaseAuth.getInstance()
val emailEditText = findViewById<EditText>(R.id.emailEditText)
val passwordEditText = findViewById<EditText>(R.id.passwordEditText)
val loginButton = findViewById<Button>(R.id.loginButton)
val signUpButton = findViewById<Button>(R.id.signUpButton)
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build()
googleSignInClient = GoogleSignIn.getClient(this,gso)
val googleBtn : SignInButton = findViewById(R.id.googleLoginBtn)
googleBtn.setOnClickListener {
GooglesignIn()
}
loginButton.setOnClickListener{
val email = emailEditText.text.toString()
val password = passwordEditText.text.toString()
auth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
successLogin()
} else {
Toast.makeText(this, "로그인에 실패했습니다. 이메일 또는 비밀번호를 확인해주세요.", Toast.LENGTH_SHORT).show()
}
}
}// ctrl+alt+m refactor > function 안드로이드스튜디오에서 제공하는 기능
emailEditText.addTextChangedListener {
val enable = emailEditText.text.isNotEmpty() && passwordEditText.text.isNotEmpty()
loginButton.isEnabled = enable
signUpButton.isEnabled = enable
}
passwordEditText.addTextChangedListener {
val enable = emailEditText.text.isNotEmpty() && passwordEditText.text.isNotEmpty()
loginButton.isEnabled = enable
signUpButton.isEnabled = enable
}
signUpButton.setOnClickListener {
val email = emailEditText.text.toString()
val password = passwordEditText.text.toString()
auth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
Toast.makeText(this, "회원가입을 성공했습니다. 로그인 버튼을 눌러 로그인해주세요.", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this, "이미 가입한 이메일이거나, 회원가입에 실패했습니다.", Toast.LENGTH_SHORT).show()
}
}
}
}
private fun GooglesignIn() {
val signInIntent = googleSignInClient.signInIntent
startActivityForResult(signInIntent, GOOGLE_REQUEST_CODE)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
// Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
if (requestCode == GOOGLE_REQUEST_CODE) {
val task = GoogleSignIn.getSignedInAccountFromIntent(data)
try {
// Google Sign In was successful, authenticate with Firebase
val account = task.getResult(ApiException::class.java)!!
Log.d(TAG, "firebaseAuthWithGoogle:" + account.id)
firebaseAuthWithGoogle(account.idToken!!)
} catch (e: ApiException) {
// Google Sign In failed, update UI appropriately
Log.w(TAG, "Google sign in failed", e)
Toast.makeText(this, "로그인 실패", Toast.LENGTH_SHORT).show()
}
}
}
private fun firebaseAuthWithGoogle(idToken: String) {
val credential = GoogleAuthProvider.getCredential(idToken, null)
auth?.signInWithCredential(credential)
?.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
// Sign in success, update UI with the signed-in user's information
Log.d(TAG, "로그인 성공")
val user = auth!!.currentUser
successLogin()
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "signInWithCredential:failure", task.exception)
}
}
}
private fun initLoginButton() {
val loginButton = findViewById<Button>(R.id.loginButton)
loginButton.setOnClickListener {
val email = getInputEmail()
val password = getInputPassword()
auth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(this) { task ->
if ( task.isSuccessful ) {
Toast.makeText(this, "로그인에 성공했습니다", Toast.LENGTH_SHORT).show()
successLogin()
// 로그인에 성공했다면 액티비티 종료
} else {
Toast.makeText(this, "로그인에 실패했습니다. 이메일 또는 전화번호를 확인해주세요", Toast.LENGTH_SHORT).show()
}
}
}
}
// 예외처리
private fun initEmailAndPasswordEditText() {
val emailEditText = findViewById<EditText>(R.id.emailEditText)
val passwordEditText = findViewById<EditText>(R.id.passwordEditText)
val loginButton = findViewById<Button>(R.id.loginButton)
val signUpButton = findViewById<Button>(R.id.signUpButton)
emailEditText.addTextChangedListener {
val enable = emailEditText.text.isNotEmpty() && passwordEditText.text.isNotEmpty()
loginButton.isEnabled = enable
signUpButton.isEnabled = enable
}
passwordEditText.addTextChangedListener {
val enable = emailEditText.text.isNotEmpty() && passwordEditText.text.isNotEmpty()
loginButton.isEnabled = enable
signUpButton.isEnabled = enable
}
}
private fun getInputEmail(): String {
return findViewById<EditText>(R.id.emailEditText).text.toString()
}
private fun getInputPassword(): String {
return findViewById<EditText>(R.id.passwordEditText).text.toString()
}
private fun successLogin() {
if (auth.currentUser == null) {
Toast.makeText(this, "로그인에 실패했습니다. 다시 시도해주세요.", Toast.LENGTH_SHORT).show()
return
}
val userId: String = auth.currentUser?.uid.orEmpty() //null이라면 빈값을 넣어줌
val currentUserDb = Firebase.database.reference.child("Users").child(userId)
val user = mutableMapOf<String, Any>()
user["userId"] = userId
currentUserDb.updateChildren(user)
finish()
}
}
LoginActivity.kt 코드
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="24dp">
<EditText
android:id="@+id/emailEditText"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/passwordEditText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:inputType="textPassword"
app:layout_constraintTop_toBottomOf="@+id/emailEditText"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>
<Button
android:id="@+id/loginButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="로그인"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/googleSignInBtn" />
<Button
android:id="@+id/signUpButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:text="회원가입"
app:layout_constraintEnd_toStartOf="@+id/loginButton"
app:layout_constraintTop_toBottomOf="@id/googleSignInBtn" />
<Button
android:id="@+id/googleSignInBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/passwordEditText"
app:layout_constraintStart_toStartOf="parent"
android:text="구글로그인"
app:layout_constraintEnd_toEndOf="parent"
tools:ignore="MissingConstraints"></Button>
</androidx.constraintlayout.widget.ConstraintLayout>
activity_login.xml 코드
'내맘대로 공부 > kotlin' 카테고리의 다른 글
Kotlin Collection 개념 (0) | 2021.07.11 |
---|---|
BMI 계산기 구현 (0) | 2021.07.10 |
Kotlin 개발 vs Java 개발 (0) | 2021.07.05 |
kotlin 문법 훑어보기 (+추가) (1) | 2021.07.05 |