Skip to content

Commit

Permalink
[#30] 로그인 기능 추가
Browse files Browse the repository at this point in the history
- Google OneTabSiginin 작업
  • Loading branch information
ethan-223 committed Sep 4, 2022
1 parent a4070d4 commit ad6d58b
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 2 deletions.
3 changes: 3 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ android {
def localProperties = new Properties()
localProperties.load(rootProject.file('./local.properties').newDataInputStream())
buildConfigField("String", "BASE_URL", localProperties['baseUrl'])
buildConfigField("String", "WEB_CLIENT_ID", localProperties["webClientId"])
}

signingConfigs {
Expand Down Expand Up @@ -89,6 +90,8 @@ dependencies {
implementation platform('com.google.firebase:firebase-bom:29.2.0')
implementation 'com.google.firebase:firebase-analytics-ktx'
implementation 'com.google.firebase:firebase-crashlytics-ktx'
implementation 'com.google.firebase:firebase-auth-ktx'
implementation 'com.google.android.gms:play-services-auth:20.1.0'

// Hilt
implementation "com.google.dagger:hilt-android:$hilt_version"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.app.Activity
import android.widget.Toast
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentActivity
import com.moyerun.moyeorun_android.R

fun Activity.toast(msg: String, isShort: Boolean = true) {
Toast.makeText(this, msg, if (isShort) Toast.LENGTH_SHORT else Toast.LENGTH_LONG).show()
Expand All @@ -14,4 +15,8 @@ inline fun FragmentActivity.showAllowingStateLoss(
dialogFragmentFactory: () -> DialogFragment
) {
supportFragmentManager.showAllowingStateLoss(tag, dialogFragmentFactory)
}

fun Activity.showNetworkErrorToast() {
toast(getString(R.string.toast_network_error))
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.widget.Toast
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import com.moyerun.moyeorun_android.R

fun Fragment.toast(msg: String, isShort: Boolean = false) {
Toast.makeText(context, msg, if (isShort) Toast.LENGTH_SHORT else Toast.LENGTH_LONG).show()
Expand All @@ -19,4 +20,8 @@ inline fun FragmentManager?.showAllowingStateLoss(
val transaction = beginTransaction()
transaction.add(dialogFragmentFactory(), tag)
transaction.commitAllowingStateLoss()
}

fun Fragment.showNetworkErrorToast() {
toast(getString(R.string.toast_network_error))
}
101 changes: 99 additions & 2 deletions app/src/main/java/com/moyerun/moyeorun_android/login/LoginActivity.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,114 @@
package com.moyerun.moyeorun_android.login

import androidx.appcompat.app.AppCompatActivity
import android.content.Intent
import android.content.IntentSender
import android.os.Bundle
import android.provider.Settings
import androidx.activity.result.IntentSenderRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.auth.api.identity.BeginSignInRequest
import com.google.android.gms.auth.api.identity.Identity
import com.google.android.gms.auth.api.identity.SignInClient
import com.google.android.gms.common.api.ApiException
import com.google.android.gms.common.api.CommonStatusCodes
import com.moyerun.moyeorun_android.BuildConfig
import com.moyerun.moyeorun_android.R
import com.moyerun.moyeorun_android.common.Lg
import com.moyerun.moyeorun_android.common.extension.showNetworkErrorToast
import com.moyerun.moyeorun_android.common.extension.toast
import com.moyerun.moyeorun_android.databinding.ActivityLoginBinding


class LoginActivity : AppCompatActivity() {

private val oneTapClient: SignInClient by lazy { Identity.getSignInClient(this) }
private val signInRequest: BeginSignInRequest by lazy { getBeginSignInRequest() }

private val beginSignInResultLauncher =
registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result ->
if (result != null) {
try {
val credential = oneTapClient.getSignInCredentialFromIntent(result.data)
val idToken = credential.googleIdToken
if (idToken != null) {
//Todo: 서버에 보내서 인증 @winter223
// Todo: Firebase crashlytics userId 세팅
Lg.d("Success. token : $idToken")
} else {
showUnknownErrorToast()
//Todo: #31 을 rebase 하고 주석 풀기
// Lg.fe("No ID token")
}
} catch (e: ApiException) {
when (e.statusCode) {
CommonStatusCodes.CANCELED -> { /*Doing nothing*/ }
CommonStatusCodes.NETWORK_ERROR -> {
showNetworkErrorToast()
Lg.e("One-tap encountered a network error. $e")
}
else -> {
showUnknownErrorToast()
//Todo: #31 을 rebase 하고 주석 풀기
// Lg.fe("Couldn't get credential from result.", e)
}
}
}
}
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityLoginBinding.inflate(layoutInflater)
setContentView(binding.root)

binding.buttonLoginGoogle.setOnClickListener {
//Todo: 구글 로그인 작업 @winter223
oneTapClient.beginSignIn(signInRequest)
.addOnSuccessListener(this) { result ->
try {
val intentSenderRequest =
IntentSenderRequest.Builder(result.pendingIntent.intentSender).build()
beginSignInResultLauncher.launch(intentSenderRequest)
} catch (e: IntentSender.SendIntentException) {
showUnknownErrorToast()
// Lg.fe("Couldn't start One Tab UI", e)
}
}
.addOnFailureListener(this) {
// 기기에 등록된 계정이 없는 경우 호출
startDeviceGoogleSignInActivity()
//Todo: #31 을 rebase 하고 주석 풀기
// 간혹 등록된 계정이 있는데도 해당 콜백을 타는 경우가 있어서 로깅
// Lg.fe("No Google Accounts found", it)
}
}
}

private fun startDeviceGoogleSignInActivity() {
startActivity(Intent(Settings.ACTION_ADD_ACCOUNT).apply {
addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)
flags = Intent.FLAG_ACTIVITY_NEW_TASK
putExtra(Settings.EXTRA_ACCOUNT_TYPES, arrayOf("com.google"))
})
}

private fun getBeginSignInRequest(): BeginSignInRequest {
return BeginSignInRequest.builder()
.setGoogleIdTokenRequestOptions(
BeginSignInRequest.GoogleIdTokenRequestOptions.builder()
.setSupported(true)
.setServerClientId(BuildConfig.WEB_CLIENT_ID)
// false 로 설정해서 앱에 로그인한 적이 있는 계정뿐만 아니라
// 기기에 등록된 구글 계정을 모두 보여준다
.setFilterByAuthorizedAccounts(false)
.build()
)
// 하나의 계정만 있다면 자동으로 선택
.setAutoSelectEnabled(true)
.build()
}

private fun showUnknownErrorToast() {
toast(getString(R.string.login_toast_unknown_error))
}
}
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
<!-- Common -->
<string name="cancel">취소</string>
<string name="ok">확인</string>
<string name="toast_network_error">네트워크 연결 상태를 확인해주세요.</string>

<!-- Login -->
<string name="login_button_start">시작하기</string>
<string name="login_button_google">구글 계정으로 로그인</string>
<string name="login_toast_unknown_error">로그인에 실패하였습니다.</string>
</resources>

0 comments on commit ad6d58b

Please sign in to comment.