deprecated된 firebase dynamic link 없이 Firebase email link authentication 구현하기 - 1
DoDoBest
·2024. 9. 11. 23:51
2025년 8월 25일부터 Firebase dynamic Link(FDL)가 deprecated 되어 사용할 수 없게 됩니다. Deprecation 문서에 따르면 신규 프로젝트 생성자는 FDL을 사용할 수 없고, Firebase email link authentication에 한해서 고객센터에 문의하면 FDL을 사용할 수 있다고 합니다. (문서와 다르게 신규 프로젝트도 Firebase Console에서 Run 탭 하위의 Dynamic Links에서 사용할 수 있습니다.)
Q. I need to onboard onto Firebase Dynamic Links to enable email link auth in Firebase Authentication. What should I do?
A. It currently is not possible to newly onboard onto Firebase Dynamic Links if your Firebase project doesn't already have FDL enabled as of the sunset announcement date on August 25th, 2023.
If you need to enable Firebase Dynamic Links to enable email link authentication, please contact Firebase Support and we'll reach back to you to help get you configured.
https://firebase.google.com/support/dynamic-links-faq?authuser=0#i_need_to_onboard_onto_firebase_dynamic_links_to_enable_email_link_auth_in_firebase_authentication_what_should_i_do
따라서 migration 가이드에 따라 firebase hosting과 App Link를 이용해 Firebase email authentication을 구현해보겠습니다.
Hosting 구현 ( App Hosting 아닙니다 )
Hosting 카테고리에서 get started를 누릅니다.
NodeJS 설치
Node.js(LTS)를 설치합니다.
이후 커멘드 창을 열고, 아래 명령어를 실행합니다.
npm install -g firebase-tools
Firebase 계정, 프로젝트 설정
아래 명령어를 입력하고 Firebase 구글 계정을 연결합니다.
firebase logn
firebase 프로젝트를 생성할 경로로 이동한 후, 아래 명령어를 입력합니다.
firebase init
이후 y를 누르고 Hosting을 선택한 후 진행합니다.
Use an existing project를 선택한 후, hosting을 설정할 프로젝트를 선택합니다.
directory 이름으로 build를 입력합니다.
email link authentication을 구현하는 과정에서 필요하지 않기 때문에 single-page app, automatic build 모두 N을 입력합니다.
Configuration file 생성
App Link를 안전하게 사용하기 위한 설정 파일을 생성합니다.
In order to use App Links, you must host a configuration file that helps establish a secure association between the domain used in your links and your app. For App Links, this is the assetlinks.json file.
프로젝트 하위에 .well-known 폴더를 생성합니다.
assetlinks.json 파일을 생성합니다.
아래와 같은 값을 입력합니다. 그대로 입력하면 안 되고, target 하위의 값은 수정해야 합니다.
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.bestapp.zipbab",
"sha256_cert_fingerprints":
["SHA-256 값"]
}
}]
namespace : 이름을 지정합니다.
package_name : app build.gradle에 있는 패키지 이름을 지정합니다.
sha256_cert_fingerprints : Google Play Console - 설정 - 앱 서명에서 SHA-256 인증서 지문을 사용합니다.
아직 프로젝트를 배포하지 않았다면, Users 폴더 하위에서 .android 폴더의 debug.keystore를 이용하면 SHA 256 값을 추출할 수 있다고 합니다.
Android App Link assitant를 이용해도 SHA-256 값을 생성할 수 있습니다.
https://developer.android.com/studio/write/app-link-indexing
SHA-256 값은 Firebase Project settings에도 추가해줍니다.
다음으로 root 프로젝트 하위에 있는 firebase.json에 headers를 추가합니다.
{
"hosting": {
"public": "build",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"headers": [
{
"source": "/.well-known/assetlinks.json",
"headers": [
{
"key": "Content-Type",
"value": "application/json"
}
]
}
]
}
}
변경사항을 반영하기 위해 커멘트 창에서 아래 명령어를 입력합니다.
firebase deploy
브라우저에서 호스팅 주소가 정상적으로 동작하는지 확인합니다.
https://Xxx.web.app/.well-known/assetlinks.json
Firebase Authentication 활성화
Authentication - Sign-in method 탭에서 Email provider를 활성화 합니다.
Templates 탭으로 이동한 후, 인증 메일 형태를 변경합니다.
무료 요금제인 Spark는 기본 템플릿만 사용 가능하고, 변경하기 위해서는 Blaze로 업그레이드 해야 합니다.
저는 Spark를 사용하기 때문에 하단에 Template language를 변경해서 인증 이메일이 한국어로 발송되도록만 설정했습니다.
Android Email Authentication code 구현
이제 인증 메일을 발송하기 위한 코드를 작성하겠습니다.
의존성 추가
toml에 firebase auth, play service auth 의존성을 추가합니다.
[versions]
firebaseBom = "33.0.0"
playServiceAuth = "21.2.0"
[libraries]
firebase-bom = { group = "com.google.firebase", name = "firebase-bom", version.ref = "firebaseBom" }
firebase-firebase-auth = { group = "com.google.firebase", name = "firebase-auth" }
gms-play-service-auth = { group = "com.google.android.gms", name = "play-services-auth", version.ref = "playServiceAuth" }
Auth를 사용할 모듈 build gradle에 의존성을 추가합니다.
...
dependencies {
// Import the Firebase BoM
implementation(platform(libs.firebase.bom))
implementation(libs.firebase.firebase.auth)
implementation(libs.gms.play.service.auth)
}
발송 코드 작성
인증 메일을 발송하는 코드 입니다.
인증 메일을 발송하기 위해서는 사용자 메일이 Firebase Authentication Users 풀에 등록되어야 합니다. 그래서 유저를 먼저 등록했으며, 등록에 성공한 경우 인증 메일을 발송했습니다.
이미 가입된 사용자가 다른 이메일로 변경하는 경우도 처리했습니다.
suspend fun sendCodeToEmail(email: String, password: String): VerifyStateEntity {
val user = Firebase.auth.currentUser
if (user == null) {
return try {
// 사용자가 입력한 메일로 User를 생성한다.
val isSuccess =
Firebase.auth.createUserWithEmailAndPassword(email, password).doneSuccessful()
if (isSuccess) {
// 사용자 생성에 성공하면 인증 메일을 보낸다.
val sendEmailResult =
Firebase.auth.currentUser?.sendEmailVerification()?.doneSuccessful()
?: false
if (sendEmailResult) {
VerifyStateEntity.Success
} else {
VerifyStateEntity.FailAtSendVerificationEmail
}
} else {
VerifyStateEntity.Fail
}
} catch (e: FirebaseAuthUserCollisionException) { // 이미 가입된 사용자인 경우
VerifyStateEntity.AlreadyUsedEmail
} catch (e: FirebaseAuthWeakPasswordException) { // 비밀번호가 6자리보다 짭은 경우
VerifyStateEntity.PasswordTooShort
}
} else { // 이미 등록된 계정에서 이메일을 변경하는 경우
if (user.email == email) { // 현재 등록된 메일과 동일한 메일을 입력한 경우
return VerifyStateEntity.AlreadyUsedEmail
}
try {
// 새로운 메일로 인증 메일을 보낸다.
val isSuccess = user.verifyBeforeUpdateEmail(email).doneSuccessful()
return if (isSuccess) {
VerifyStateEntity.Success
} else {
VerifyStateEntity.Fail
}
} catch (_: FirebaseAuthInvalidUserException) {
resetAuthState()
return VerifyStateEntity.Fail
} catch (_: FirebaseAuthRecentLoginRequiredException) { // https://firebase.google.com/docs/auth/android/manage-users?hl=en#re-authenticate_a_user
// 로그인한지 시간이 많이 경과된 경우, 이메일을 변경하기 위해서는 로그인 상태를 갱신해야 합니다.
val credential = EmailAuthProvider.getCredential(user.email ?: "", password)
// 재인증 이후에도 실패할 경우 Server 단에서 처리하도록 Fail을 리턴했습니다.
return try {
user.reauthenticate(credential).await()
val isSuccess = user.verifyBeforeUpdateEmail(email).doneSuccessful()
if (isSuccess) {
VerifyStateEntity.Success
} else {
VerifyStateEntity.Fail
}
} catch (_: Exception) {
VerifyStateEntity.Fail
}
}
}
}
fun resetAuthState() {
Firebase.auth.signOut()
}
sealed interface VerifyStateEntity {
data object Success : VerifyStateEntity
data object AlreadyUsedEmail : VerifyStateEntity
data object FailAtSendVerificationEmail : VerifyStateEntity
data object Fail : VerifyStateEntity
data object PasswordTooShort : VerifyStateEntity
}
다른 예제와 다른 점은 ActionCodeSettings를 지정하지 않는 것 입니다. ActionCodeSettings를 sendEmailVerification의 파라미터로 전달하면 Firebase Dynamic Link를 사용하게 됩니다.
지금까지 설정한 코드는 FDL이 아닌 Hosting을 이용한 방식이기 때문에 Runtime에 아래와 같은 Exception이 발생합니다.
The provided dynamic link domain is not configured or authorized for the current project
private val actionCodeSettings: ActionCodeSettings = actionCodeSettings {
url = BuildConfig.FIREBASE_HOSTING_LINK
handleCodeInApp = true
setAndroidPackageName(
"com.bestapp.zipbab",
true,
"10"
)
}
코드를 실행하면 인증 메일을 확인할 수 있습니다.
마무리
다음 글에서는 Flow를 이용해 이메일의 인증 여부를 observing 하는 것과 인증 메일을 클릭했을 때, 설치된 앱 화면으로 돌아오도록 설정하는 코드를 살펴보겠습니다.
https://dodobest.tistory.com/121
'학습' 카테고리의 다른 글
deprecated된 firebase dynamic link 없이 Firebase email link authentication 구현하기 - 2 (0) | 2024.09.16 |
---|---|
Safe Navigation Action (0) | 2024.08.22 |
Flow, Channel, ChannelFlow, CallbackFlow (0) | 2024.08.15 |
RecyclerView Itemdecoration 올바르게 사용하기 (0) | 2024.07.24 |
왜 repeatOnLifecycle 앞에 viewLifecycleOwner를 붙여야할까? (0) | 2024.06.26 |