1. 파이어 베이스 연동 작업
- 파이어 베이스 홈페이지에서 프로젝트를 추가한 후에 앱과 연동 작업을 진행했습니다.
패키지 명을 앱 단위 build.gradle에서 불러와 입력하였습니다.
sha-1는 나중에 다시 설정 해 줄 수 있습니다.
2. vitameansHospital 앱 내의 폴더 안에 google-services.json 파일을 넣어줍니다.
3. 프로젝트 수준의 build.gradle (<project>/build.gradle): 에 해당 코드를 입력해줍니다.
buildscript {
repositories {
// Check that you have the following line (if not, add it):
google() // Google's Maven repository
}
dependencies {
...
// Add this line
classpath 'com.google.gms:google-services:4.3.8'
}
}
allprojects {
...
repositories {
// Check that you have the following line (if not, add it):
google() // Google's Maven repository
...
}
}
4. 앱 수준의 build.gradle (<project>/<app-module>/build.gradle): 에 해당 코드를 입력해줍니다.
apply plugin: 'com.android.application'
// Add this line
apply plugin: 'com.google.gms.google-services'
dependencies {
// Import the Firebase BoM
implementation platform('com.google.firebase:firebase-bom:28.1.0')
// Add the dependency for the Firebase SDK for Google Analytics
// When using the BoM, don't specify versions in Firebase dependencies
implementation 'com.google.firebase:firebase-analytics-ktx'
// Add the dependencies for any other desired Firebase products
// https://firebase.google.com/docs/android/setup#available-libraries
}
2. SHA-1인증서 지문 등록
전화번호 로그인 구현을 위해서는 SHA-1 키가 있어야 전화번호 인증이 가능합니다.
1. cmd 창을 키고 C:\Users\%username%\.android로 이동해줍니다.
2. keytool -list -v -keystore debug.keystore 를 입력해줍니다.
sha-1 같은 경우 비밀번호를 필요치 않아서 enter를 누르시면 넘어가집니다.
저 같은 경우 java가 깔려 있지 않았어서 key값이 존재하지 않았습니다. (덕분에 2시간 정도의 삽질 …)
**자바가 깔려 있지 않은 경우 **
- 자바를 다운로드한다.
- cmd 내에서 C:\Program Files (x86)\Java\jre1.8.0_291\bin 로 이동해준다.
- keytool -list -v -keystore "C:\Users\yumjj.android\debug.keystore" -alias androiddebugkey -storepass android -keypass android 를 입력해준다.
파이어베이스 홈페이지 콘솔 내 프로젝트 설정에서 SHA 인증서 지문을 등록해주면 완료입니다.
사전 준비는 끝나고 직접 구현에 들어가겠습니다.
1.전화번호 인증 페이지 ui 제작
해당 페이지에서 번호 인증이 이루어집니다.
activity_phonenumber.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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/iv_back"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_margin="5dp"
android:src="@drawable/ic_back"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
android:id="@+id/tv_phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="전화번호 인증"
android:fontFamily="@font/spoqa_han_sans_neo_bold"
android:textSize="25dp"
android:textColor="@color/black"
android:layout_marginTop="20dp"
android:layout_marginLeft="30dp"
app:layout_constraintTop_toBottomOf="@+id/iv_back"
app:layout_constraintLeft_toLeftOf="parent"/>
<EditText
android:id="@+id/et_phone_sign"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="140dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="120dp"
android:hint="전화번호를 입력해주세요"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/tv_phone" />
<Button
android:id="@+id/btn_certification"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="137dp"
android:backgroundTint="@color/grey50Light"
android:text="인증요청"
android:textColor="@color/browser_actions_title_color"
app:layout_constraintLeft_toRightOf="@id/et_phone_sign"
app:layout_constraintTop_toTopOf="@id/tv_phone" />
<EditText
android:id="@+id/et_phone_certification"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="80dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:hint="인증 번호 입력"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/et_phone_sign" />
<Button
android:id="@+id/btn_certification_check"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="80dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:textColor="@color/black"
android:text="인증하기"
android:backgroundTint="@color/grey300"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/et_phone_certification"/>
</androidx.constraintlayout.widget.ConstraintLayout>
2.전화번호 인증 기능 구현
로직
startPhoneNumberVerification으로 인증번호 발송 PhoneAuthProvider.OnVerificationStateChangedCallbacks() 내의 onCodeSent 에서 인증 번호 및 토큰 값 획득
val credential = PhoneAuthProvider.getCredential(verificationId!!, code) 에 onCodeSent 에서 받은 인증 번호와 전화번호를 통해 받은 인증 코드를 각각 입력하여 객체 생성
signInWithPhoneAuthCredential(credential: PhoneAuthCredential)에 위에서 만든 객체 입력하면 로그인 끝
1. 모듈(앱 수준) Gradle 파일(일반적으로 app/build.gradle)에서 Firebase 인증 Android 라이브러리의 종속 항목을 선언합니다.
dependencies {
// Import the BoM for the Firebase platform
implementation platform('com.google.firebase:firebase-bom:28.0.1')
// Declare the dependency for the Firebase Authentication library
// When using the BoM, you don't specify versions in Firebase library dependencies
implementation 'com.google.firebase:firebase-auth-ktx'
}
2. 사용자 전화로 인증 코드 전송
PhoneAuthProvider.verifyPhoneNumber 메서드에 전화번호를 전달하여 Firebase가 사용자의 전화번호를 확인하도록 요청합니다.
val options = PhoneAuthOptions.newBuilder(auth)
.setPhoneNumber(phoneNumber) // Phone number to verify
.setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
.setActivity(this) // Activity (for callback binding)
.setCallbacks(callbacks) // OnVerificationStateChangedCallbacks
.build()
PhoneAuthProvider.verifyPhoneNumber(options)
PhoneAuthProvider.verifyPhoneNumber를 호출할 때는 요청 결과를 처리하는 콜백 함수의 구현을 포함하는 OnVerificationStateChangedCallbacks의 인스턴스도 제공해야 합니다. 예를 들면 다음과 같습니다.
private var callbacks = object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
override fun onVerificationCompleted(credential: PhoneAuthCredential) {
signInWithPhoneAuthCredential(credential)
}
override fun onVerificationFailed(e: FirebaseException) {
if (e is FirebaseAuthInvalidCredentialsException) {
// Invalid request
} else if (e is FirebaseTooManyRequestsException) {
// The SMS quota for the project has been exceeded
}
}
override fun onCodeSent(
verificationId: String,
token: PhoneAuthProvider.ForceResendingToken
) {
storedVerificationId = verificationId
resendToken = token
}
}
3. PhoneAuthCredential 객체 만들기
사용자가 Firebase에서 사용자의 전화로 보낸 인증 코드를 입력하면 인증 코드 및 onCodeSent 또는 onCodeAutoRetrievalTimeOut 콜백에 전달된 인증 ID를 사용하여 PhoneAuthCredential 객체를 만듭니다.
PhoneAuthCredential 객체를 만들려면 다음과 같이 PhoneAuthProvider.getCredential을 호출합니다.
val credential = PhoneAuthProvider.getCredential(verificationId!!, code)
4. 사용자 로그인
onVerificationCompleted 콜백 또는 PhoneAuthProvider.getCredential 호출을 통해 PhoneAuthCredential 객체를 가져온 후 FirebaseAuth.signInWithCredential에 PhoneAuthCredential 객체를 전달하여 로그인 과정을 완료합니다.
private fun signInWithPhoneAuthCredential(credential: PhoneAuthCredential) {
auth.signInWithCredential(credential)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
// Sign in success, update UI with the signed-in user's information
Log.d(ContentValues.TAG, "signInWithCredential:success")
val user = task.result?.user
startActivity(Intent(this, MainAct::class.java))
} else {
// Sign in failed, display a message and update the UI
Log.w(ContentValues.TAG, "signInWithCredential:failure", task.exception)
if (task.exception is FirebaseAuthInvalidCredentialsException) {
}
// Update UI
}
}
}
phoneNumberAct.kt 전체코드
package com.example.vitameanshospital.login
import android.content.ContentValues
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.vitameanshospital.MainAct
import com.example.vitameanshospital.R
import com.google.firebase.FirebaseException
import com.google.firebase.FirebaseTooManyRequestsException
import com.google.firebase.auth.*
import com.google.firebase.auth.ktx.auth
import com.google.firebase.ktx.Firebase
import kotlinx.android.synthetic.main.activity_hospital.*
import kotlinx.android.synthetic.main.activity_phonenumber.*
import java.util.concurrent.TimeUnit
class PhoneNumberAct:AppCompatActivity() {
private lateinit var auth: FirebaseAuth
private lateinit var resendToken: PhoneAuthProvider.ForceResendingToken
private var callbacks = object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
override fun onVerificationCompleted(credential: PhoneAuthCredential) {
signInWithPhoneAuthCredential(credential)
}
override fun onVerificationFailed(e: FirebaseException) {
if (e is FirebaseAuthInvalidCredentialsException) {
// Invalid request
} else if (e is FirebaseTooManyRequestsException) {
// The SMS quota for the project has been exceeded
}
}
override fun onCodeSent(
verificationId: String,
token: PhoneAuthProvider.ForceResendingToken
) {
storedVerificationId = verificationId
resendToken = token
}
}
private var storedVerificationId: String? = ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_phonenumber)
auth = Firebase.auth
iv_back.setOnClickListener {
finish()
}
btn_certification.setOnClickListener {
val phoneNumber =et_phone_sign.text.toString()
if(phoneNumber==null){
Toast.makeText(applicationContext, "전화번호를 입력해주세요", Toast.LENGTH_SHORT).show()
}
else{
startPhoneNumberVerification(phoneNumber)
}
}
btn_certification_check.setOnClickListener {
val certificationCode = et_phone_certification.text.toString()
verifyPhoneNumberWithCode(storedVerificationId,certificationCode)
}
}
override fun onStart() {
super.onStart()
// Check if user is signed in (non-null) and update UI accordingly.
val currentUser = auth.currentUser
}
private fun startPhoneNumberVerification(phoneNumber: String) {
// [START start_phone_auth]
val options = PhoneAuthOptions.newBuilder(auth)
.setPhoneNumber(phoneNumber) // Phone number to verify
.setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
.setActivity(this) // Activity (for callback binding)
.setCallbacks(callbacks) // OnVerificationStateChangedCallbacks
.build()
PhoneAuthProvider.verifyPhoneNumber(options)
// [END start_phone_auth]
}
private fun verifyPhoneNumberWithCode(verificationId: String?, code: String) {
val credential = PhoneAuthProvider.getCredential(verificationId!!, code)
signInWithPhoneAuthCredential(credential)
}
private fun signInWithPhoneAuthCredential(credential: PhoneAuthCredential) {
auth.signInWithCredential(credential)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
// Sign in success, update UI with the signed-in user's information
Log.d(ContentValues.TAG, "signInWithCredential:success")
val user = task.result?.user
startActivity(Intent(this, MainAct::class.java))
} else {
// Sign in failed, display a message and update the UI
Log.w(ContentValues.TAG, "signInWithCredential:failure", task.exception)
if (task.exception is FirebaseAuthInvalidCredentialsException) {
}
// Update UI
}
}
}
}
'안드로이드 개발 > 코틀린' 카테고리의 다른 글
Live Data 와 Coroutines Flow (0) | 2022.05.18 |
---|---|
[Kotlin] Lottie 애니메이션 사용법 (0) | 2021.08.10 |
코틀린의 느낌표 물음표(널가능성) (0) | 2021.03.25 |
[Kotlin] 코틀린의 장점 (0) | 2021.03.22 |