Tinder Clone Coding Part 1(Firebase Authenetication)
Component
이번 실습에서 진행할 내용
-
Firebase Authenetication (SNS로 로그인하기)
-
Firebase Realtime Database (서버 데이터 베이스)
-
CardStackView(카드 스택 뷰 구현, Opensource)
Create Firebase Project, Authenetication, 이메일 사용 설저 ON
라이브러리를 포함시키기 위해서 아래와 같은 코드들을 추가해야한다.
Android Studio Arctic Fox 버전 이후로는 조금 달라진 코드 모습을 볼 수 있다.
// setting.gradle
// 모드를 변경해야함
dependencyResolutionManagement {
// FAIL_ON_PROJECT_REPOS -> PREFER_PROJECT
repositoriesMode.set(RepositoriesMode.PREFER_PROJECT)
repositories {
google()
mavenCentral()
}
}
// project level - build.gradle
buildscript {
dependencies {
classpath 'com.google.gms:google-services:4.3.10'
}
}
plugins {
// ...
id 'com.google.gms.google-services'
}
dependencies {
// 파이어베이스
implementation platform('com.google.firebase:firebase-bom:29.3.1')
//파이어 베이스 Auth
implementation 'com.google.firebase:firebase-auth-ktx'
}
# Realtime Database 지역 미국, 테스트 버전으로 생성
# 데이터 베이스 생성 후 google-service.json 파일을 최신화 버전으로 업데이트 해주기
# LoginActivity.kt, activity_login.xml 생성
<?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"
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_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/emailEditText" />
<Button
android:id="@+id/loginButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="로그인"
app:layout_constraintEnd_toEndOf="@id/passwordEditText"
app:layout_constraintTop_toBottomOf="@id/passwordEditText" />
<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/passwordEditText" />
</androidx.constraintlayout.widget.ConstraintLayout>
// LoginActivity.kt
package com.jyh.snsauth
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.firebase.auth.FirebaseAuth
import com.google.firebase.auth.ktx.auth
import com.google.firebase.ktx.Firebase
class LoginActivity:AppCompatActivity() {
// FirebaseAuth 객체 변수
lateinit var auth:FirebaseAuth
lateinit var emailEditText:EditText
lateinit var passwordEditText:EditText
lateinit var loginButton:Button
lateinit var signupButton:Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
auth = Firebase.auth // Firebase.getInstance()
emailEditText = findViewById<EditText>(R.id.emailEditText)
passwordEditText = findViewById<EditText>(R.id.passwordEditText)
initLoginButton()
initSignupButton()
initEmailAndPasswordEditText()
}
private fun initLoginButton() {
loginButton = findViewById<Button>(R.id.loginButton)
loginButton.isEnabled= false
loginButton.setOnClickListener {
val email = getInputEmail()
val password = getInputPassword()
// 파이어베이스 이메일 로그인 기능
auth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(this){
if(it.isSuccessful){
finish()
}
else{
Toast.makeText(this, "$email $password",Toast.LENGTH_SHORT).show()
}
}
}
}
private fun initSignupButton() {
signupButton = findViewById<Button>(R.id.signupButton)
signupButton.isEnabled = false
signupButton.setOnClickListener {
val email = getInputEmail()
val password = getInputPassword()
auth.createUserWithEmailAndPassword(email,password)
.addOnCompleteListener(this) {
if(it.isSuccessful){
Toast.makeText(this, "회원가입 성공\n 로그인을 해주세요",Toast.LENGTH_SHORT).show()
}else{
Toast.makeText(this, "회원가입 실패",Toast.LENGTH_SHORT).show()
}
}
}
}
private fun getInputEmail():String{
return emailEditText.text.toString()
}
private fun getInputPassword() :String{
return passwordEditText.text.toString()
}
private fun initEmailAndPasswordEditText(){
emailEditText.addTextChangedListener {
val enable = emailEditText.text.isNotEmpty() && passwordEditText.text.isNotEmpty()
loginButton.isEnabled = enable
signupButton.isEnabled = enable
Log.d("tag", "$enable")
}
passwordEditText.addTextChangedListener {
val enable = emailEditText.text.isNotEmpty() && passwordEditText.text.isNotEmpty()
loginButton.isEnabled = enable
signupButton.isEnabled = enable
}
}
}
MainActivity에서 onStart() 오버라이딩
회원 정보가 없으면 자동으로 로그인 엑티비티로 이동하기!
// onStart() 메서드 오버라이딩, life cycle 복습하기
override fun onStart() {
super.onStart()
if(auth.currentUser==null){
startActivity(Intent(this, LoginActivity::class.java))
}
}
Firebase Auth 콘솔 Facebook 로그인 추가하기
- FaceBook Developer 회원 가입, 앱 추가
Facebook 로그인 기능 설정
- 로그인 -> 설정 -> 앱 ID 확인, Firebase Auth 콘솔에 Facebook ID 추가
- Firebase Auth 콘솔에 보이는 OAuth 리다이렉션 uri를 Facebook Developer 콘솔 앱의 로그인 설정에 추가
Android Facebook 공식 문서 1~5 번 진행
문서에 따라 1번 부터 5번 까지의 과정을 진행한다.
6번 부터는 릴리즈 용 키를 생성하므로 릴리즈 할 때 문서를 참고해 수행해보자
페이스북 로그인 버튼 추가하기
<com.facebook.login.widget.LoginButton
android:id="@+id/facebookLoginButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/passwordEditText" />
LoginActivity.kt에 CallbackManager 추가하기(페이스북 로그인 콜백 관리)
현재 onActivityResult() 메소드와 startActivtyForResult() 메소드는 Deprecated 되었습니다
//LoginActivity.kt
...
private val callbackManager: CallbackManager by lazy { CallbackManager.Factory.create() }
...
initFacebookLoginButton()
...
private fun initFacebookLoginButton() {
val facebookLoginButton = findViewById<LoginButton>(R.id.facebookLoginButton)
facebookLoginButton.setPermissions("email", "public_profile")
facebookLoginButton.registerCallback(callbackManager, object:FacebookCallback<LoginResult>{
override fun onSuccess(result: LoginResult) {
// 로그인 성공
val credential = FacebookAuthProvider.getCredential(result.accessToken.token)
auth.signInWithCredential(credential)
.addOnCompleteListener(this@LoginActivity) {
if(it.isSuccessful){
finish()
}else{
Toast.makeText(this@LoginActivity, "로그인 실패", Toast.LENGTH_SHORT).show()
}
}
}
override fun onCancel() {
// 로그인 중도 포기
}
override fun onError(error: FacebookException) {
// 로그인 실패, 컨택스트 this -> this@LoginActivity !!!
Toast.makeText(this@LoginActivity, "로그인 실패", Toast.LENGTH_SHORT).show()
}
})
}
...
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
callbackManager.onActivityResult(requestCode, resultCode, data)
}
앱 검수를 마치면 정상적으로 유저의 아이디를 읽어올 수 있다.