Firebase_Google_Authentication - boostcampwm-2024/and04-Nature-Album GitHub Wiki

โœ… ์ง„ํ–‰ํ•œ ๊ธฐ๋Šฅ

โœ… Firebase Google Login ๊ธฐ๋Šฅ

โœ… secrets gradle plugin๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ local.properties ํ‚ค ๊ฐ’ ์ˆจ๊ธฐ๊ธฐ

๐Ÿ’ก๋ฌธ์ œ ํ•ด๊ฒฐ ๊ณผ์ • ๊ธฐ๋ก

https://firebase.google.com/docs/auth/android/google-signin?hl=ko

Firebase Authentication ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ๊ตฌํ˜„ํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.

ํ•˜์ง€๋งŒ ํ•ด๋‹น ๋ฌธ์„œ์˜ ์ฝ”๋“œ์˜ ๋Œ€๋ถ€๋ถ„์ด deprecated ๋˜์—ˆ๊ธฐ์— ์•„๋ž˜์˜ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ๋”ฐ๋ผ๊ฐ€๊ธฐ๋กœ ํ–ˆ๋‹ค.

https://developer.android.com/identity/sign-in/credential-manager-siwg?hl=ko

์œ„ ๊ณต์‹ ๋ฌธ์„œ์—์„œ๋Š” deprecated๋œ BeginSignInRequest ๋Œ€์‹  Credential Manager ๋ฅผ ์‚ฌ์šฉํ•˜๋ผ๊ณ  ํ•œ๋‹ค.

โ“ Credential Manager๋Š” ๋ฌด์—‡์ผ๊นŒ?

Credential Manager ์— ๋Œ€ํ•ด์„œ๋Š” ์•„๋ž˜์˜ Google Developers์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

https://developers.googleblog.com/ko/simple-and-secure-sign-in-on-android-with-credential-manager-and-passkeys/

Credential Manager๋Š” Android ํ”Œ๋žซํผ์˜ ๋ฏธ๋ž˜ํ˜• ์ธ์ฆ ๋ฐฉ์‹์œผ๋กœ, ์‚ฌ์šฉ์ž๊ฐ€ ์•ฑ๊ณผ ์›น์‚ฌ์ดํŠธ์— ๋กœ๊ทธ์ธํ•˜๋Š” ๋ฐฉ์‹์„ ๊ฐ„์†Œํ™”ํ•˜๋Š” ๋™์‹œ์— ํ•œ์ธต ๊ฐ•ํ™”๋œ ๋ณด์•ˆ์„ ์ œ๊ณตํ•œ๋‹ค.

๋น„๋ฐ€๋ฒˆํ˜ธ์™€ ๋‹ค์–‘ํ•œ ๋กœ๊ทธ์ธ ๋ฐฉ์‹์œผ๋กœ ์ธํ•ด ์‚ฌ์šฉ์ž์™€ ๊ฐœ๋ฐœ์ž ๋ชจ๋‘์—๊ฒŒ ๋กœ๊ทธ์ธ ๊ณผ์ •์ด ๋ณต์žกํ•ด์งˆ ์ˆ˜ ์žˆ๋‹ค,

ํ•˜์ง€๋งŒ Credential Manager๋Š” Android์—์„œ ํŒจ์Šค์›Œ๋“œ๋ฆฌ์Šค ์ธ์ฆ ๋ฐฉ์‹(ํŒจ์Šคํ‚ค)๊ณผ ๊ธฐ์กด ๋กœ๊ทธ์ธ ๋ฐฉ์‹์„ ํ•˜๋‚˜์˜ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ํ†ตํ•ฉํ•ด ์ง€์›ํ•˜๊ณ  ์ด๋ฅผ ํ†ตํ•ด ๋ณด์•ˆ์„ฑ๊ณผ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํ–ฅ์ƒ์‹œํ‚ค๊ณ  ๊ฐœ๋ฐœ์˜ ๋ณต์žก์„ฑ์„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

ํŒจ์Šคํ‚ค๋กœ ํŒจ์Šค์›Œ๋“œ๋ฆฌ์Šค ์ธ์ฆ ์ง€์›ํ•˜๊ณ  ๋ชจ๋“  ๊ณ„์ •์„ ๋‹จ์ˆœํ•œ ์ธํ„ฐํŽ˜์ด์Šค์—์„œ ํƒญ ํ•œ ๋ฒˆ์œผ๋กœ ์ด์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.

์œ„ ์ด๋ฏธ์ง€์™€ ๊ฐ™์ด ๋™์ผ ๊ณ„์ •์— ์—ฌ๋Ÿฌ ๋กœ๊ทธ์ธ ๋ฐฉ๋ฒ•์ด ์žˆ์„ ๋•Œ, Credential Manager๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ์ตœ์ ์˜ ๋กœ๊ทธ์ธ ๋ฐฉ์‹(ํŒจ์Šคํ‚ค, ๋น„๋ฐ€๋ฒˆํ˜ธ ๋“ฑ)์„ ์ž๋™์œผ๋กœ ์„ ํƒํ•ด ์ œ๊ณตํ•œ๋‹ค.

์‚ฌ์šฉ์ž๋Š” ๋กœ๊ทธ์ธ ๋ฐฉ์‹ ๋Œ€์‹  ๊ณ„์ •๋งŒ ์„ ํƒํ•˜๋ฉด ๋‚˜๋จธ์ง€ ๊ณผ์ •์ด ์ž๋™์œผ๋กœ ์ง„ํ–‰๋˜๋ฏ€๋กœ ํŽธ๋ฆฌํ•œ ๊ฒƒ์ด๋‹ค.

Google ๋กœ๊ทธ์ธ ํ๋ฆ„

1. Credential Option๊ณผ ํ•จ๊ป˜ Credential Request ์ƒ์„ฑ

๊ฐ€์žฅ ๋จผ์ € GetCredentialRequest ๋ฅผ ์ธ์Šคํ„ด์Šคํ™” ํ•œ ํ›„ addCredentialOption() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด CredentialOption ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

val request = GetCredentialRequest.Builder()
    .addCredentialOption(googleIdOption)
    .build()

CredentialOption ์— Google ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ Key๊ฐ’์„ ๋“ฑ๋กํ•˜๊ฑฐ๋‚˜ ๋ณด์•ˆ ๊ฐ•ํ™”, ์ž๋™ ๋กœ๊ทธ์ธ ๋“ฑ์˜ ์˜ต์…˜์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

val googleIdOption = GetGoogleIdOption.Builder()
    .setFilterByAuthorizedAccounts(false)
    .setServerClientId(BuildConfig.google_web_key) //Web client td
    .setAutoSelectEnabled(false)
    .build()

2. ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด ์š”์ฒญํ•˜๊ธฐ

์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด๋ฅผ ์š”์ฒญํ•˜๊ธฐ ์œ„ํ•ด์„œ CredentialManager ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  getCredential() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ธ์ฆ์„ ์š”์ฒญํ•œ๋‹ค.

Screenshot 2024-11-12 at 11 42 14โ€ฏPM

ํ•ด๋‹น ๋ฉ”์„œ๋“œ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ request์—๋Š” ์•ž์„œ ๋งŒ๋“ค์—ˆ๋˜ GetCredentialRequest ๋ฅผ ๋„ฃ์–ด์•ผ ํ•œ๋‹ค.

์ด getCredential ํ•จ์ˆ˜๋Š” suspendCancellableCoroutine ์œผ๋กœ ์‹คํ–‰๋˜๊ธฐ์— ์ฝ”๋ฃจํ‹ด์œผ๋กœ ํ˜ธ์ถœํ•ด์•ผ ํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค.

suspendCancellableCoroutine ์— ๋Œ€ํ•ด์„œ๋Š” ์•„๋ž˜ ์˜๋ฌธ์—์„œ ์ž ๊น ์งš๊ณ  ๋„˜์–ด๊ฐˆ ์˜ˆ์ •์ด๋‹ค.

3. CustomCredential ์ถ”์ถœ

๋งŒ์•ฝ ์œ„ API๊ฐ€ ์„ฑ๊ณตํ•˜๋ฉด GoogleIdTokenCredential ๋ฐ์ดํ„ฐ์˜ ๊ฒฐ๊ณผ๊ฐ€ ํฌํ•จ๋œ CustomCredential ๋ฅผ ์ถ”์ถœํ•œ๋‹ค.

CustomCredential์˜ ์œ ํ˜•์€ GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL์˜ ๊ฐ’๊ณผ ๊ฐ™์•„์•ผ ํ•œ๋‹ค. GoogleIdTokenCredential.createFrom ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ GoogleIdTokenCredential๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

๋งŒ์•ฝ ๋ณ€ํ™˜์— ์„ฑ๊ณตํ•˜๋ฉด GoogleIdTokenCredential ID๋ฅผ ์ถ”์ถœํ•˜๊ณ  ๊ฒ€์ฆํ•œ ํ›„ ์„œ๋ฒ„์—์„œ ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด๋ฅผ ์ธ์ฆํ•œ๋‹ค.

GoogleIdTokenParsingException๊ณผ ํ•จ๊ป˜ ๋ณ€ํ™˜์— ์‹คํŒจํ•˜๋ฉด Google ๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฒ„์ „์„ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

val googleIdTokenCredential = GoogleIdTokenCredential
    .createFrom(credential.data)
    
val firebaseCredential = GoogleAuthProvider.getCredential(
    googleIdTokenCredential.idToken,
    null
)

Firebase Authentication์— ์—ฐ๊ฒฐ

์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธ ํ•œ ๊ตฌ๊ธ€ ๊ณ„์ •์„ Firebase Authentication์— ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•˜์—ฌ FirebaseAuth๋ฅผ ์ƒ์„ฑํ•˜๊ณ  signInWithCredential() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์—ฐ๊ฒฐํ•œ๋‹ค.

์ด๋•Œ ํ•ด๋‹น ์ธ์ž๋กœ ์œ„์—์„œ GoogleAuthProvider.getCredential ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ถ”์ถœํ–ˆ๋˜ AuthCredential์„ ๋„˜๊ฒจ์ค˜์•ผ ํ•œ๋‹ค.

auth.signInWithCredential(firebaseCredential)
    .addOnCompleteListener { authResult ->
        if (authResult.isSuccessful) {
            trySend(AuthResponse.Success)
            val user = authResult.result.user
            user?.let { user ->
                Log.d("AuthenticationManager", "${user.email}")
            }

        } else {
            Log.d("AuthenticationManager", "${authResult.exception}")
        }
    }

โ“FirebaseAuth ์ƒ์„ฑ ๋ฐฉ๋ฒ•์˜ ์ฐจ์ด์ 

FirebaseAuth ์ฝ”๋“œ ์ƒ์„ฑ ๋ฐฉ๋ฒ•์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด 2๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

*private val* auth = FirebaseAuth.getInstance() 

*private val* auth = Firebase.*auth*

๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์˜ ์ฐจ์ด๋Š” ๋ฌด์—‡์ผ๊นŒ?

1. FirebaseAuth.getInstance()

Firebase Authentication ์ดˆ๊ธฐ ๋ฒ„์ „๋ถ€ํ„ฐ ์‚ฌ์šฉ๋˜์–ด ์˜จ ์ „ํ†ต์ ์ธ ๋ฐฉ๋ฒ•์ด๋‹ค.

FirebaseAuth.getInstance() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ํ•ด๋‹น ํ”„๋กœ์ ํŠธ ๋‚ด์—์„œ ์œ ์ผํ•œ FirebaseAuth ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

2. Firebase.auth

Firebase SDK v9 ๋ฒ„์ „๋ถ€ํ„ฐ ๋„์ž…๋œ ์ƒˆ๋กœ์šด ๋ฐฉ์‹์ด๋‹ค.

Firebase์˜ ๋‹ค์–‘ํ•œ ์„œ๋น„์Šค(Authentication, Realtime Database, Cloud Firestore ๋“ฑ)๋ฅผ ํ†ตํ•ฉ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ Firebase ๊ฐ์ฒด์— ๋ฐ”๋กœ ์ ‘๊ทผํ•˜์—ฌ FireAuth ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

๐Ÿ’ก ์ฆ‰, Firebase.auth ๋ฐฉ์‹์ด ์ตœ์‹  ๋ฒ„์ „์—์„œ ๋” ๊ฐ„ํŽธํ•˜๊ฒŒ ์‚ฌ์šฉ๋˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

โ“suspendCancellableCoroutine ์€ ๋ฌด์—‡์ผ๊นŒ?

suspendCancellableCoroutine ๋Š” ์ฝ”๋ฃจํ‹ด์—์„œ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ๋•Œ, ์ž‘์—…์„ ์ค‘๋‹จํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค. ํŠนํžˆ suspendCancellableCoroutine ํ•จ์ˆ˜๋Š” ์ž‘์—…์ด ์ทจ์†Œ ๋ ๋•Œ ์ถ”๊ฐ€์ ์ธ ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” invokOnCancellation api๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

์ฃผ๋กœ ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‚˜ ์‹œ์Šคํ…œ์—์„œ ์ œ๊ณตํ•˜๋Š” ์ฝœ๋ฐฑ ๊ธฐ๋ฐ˜์˜ ๋น„๋™๊ธฐ API๋ฅผ ์ฝ”๋ฃจํ‹ด๊ณผ ํ†ตํ•ฉํ•  ๋•Œ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋œ๋‹ค.

๐Ÿ’ฅ Deprecated๋œ ๊ณต์‹ ๋ฌธ์„œ์˜ ์ฝ”๋“œ

๋ฌธ์ œ ์ •์˜

https://firebase.google.com/docs/auth/android/google-signin?hl=ko#kotlin+ktx_1

Firebase Google Authentication ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ๋ณด๊ณ  ๋”ฐ๋ผํ•˜๋ ค ํ–ˆ์œผ๋‚˜ ์˜ˆ์‹œ ์ฝ”๋“œ ์ค‘ BegingSignInRequest ๋ถ€๋ถ„์ด deprecated ๋˜์—ˆ๋‹ค.

image

image

๋ฌธ์ œ ํ•ด๊ฒฐ ๊ณผ์ •

BeginSignInRequest ๋Œ€์‹  Credential Manager ๋ฅผ ์‚ฌ์šฉํ•˜๋ผ๋Š” ์•ˆ๋‚ด ๋ฌธ๊ตฌ๋ฅผ ํ†ตํ•ด ์ˆ˜์ •ํ•˜์˜€๋‹ค.

์ธ์ฆ ๊ด€๋ฆฌ์ž๋Š” ๋‹จ์ผ API์—์„œ ์‚ฌ์šฉ์ž ์ด๋ฆ„๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ, ํŒจ์Šคํ‚ค, ์ œํœด ๋กœ๊ทธ์ธ ์†”๋ฅ˜์…˜(์˜ˆ: Google ๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธ)๊ณผ ๊ฐ™์€ ๋ฉ€ํ‹ฐ ๋กœ๊ทธ์ธ ๋ฐฉ์‹์„ ์ง€์›ํ•˜์—ฌ ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ ํ†ตํ•ฉ์„ ๊ฐ„์†Œํ™”ํ•˜๋Š” Jetpack API์ด๋‹ค.

๋˜ํ•œ ์ธ์ฆ ๋ฐฉ์‹ ์ „๋ฐ˜์—์„œ ๋กœ๊ทธ์ธ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ฉํ•˜๋ฏ€๋กœ ์‚ฌ์šฉ์ž๋Š” ์ž์‹ ์ด ์„ ํƒํ•œ ๋ฐฉ์‹๊ณผ ์ƒ๊ด€์—†์ด ๋” ๋ช…ํ™•ํ•˜๊ณ  ์‰ฝ๊ฒŒ ์•ฑ์— ๋กœ๊ทธ์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ’ฅ Cannot find a matching credential

๋ฌธ์ œ ์ •์˜

๊ตฌ๊ธ€ ๋กœ๊ทธ์ธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์‹คํ–‰ํ–ˆ์ง€๋งŒ, ์•ฑ์ด ๋ฐ”๋กœ ์ข…๋ฃŒ๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒ

์—๋Ÿฌ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

setFilterByAuthorizedAccounts true แ„†แ…ฎแ†ซแ„Œแ…ฆ

๋ฌธ์ œ ํ•ด๊ฒฐ ๊ณผ์ •

๊ณต์‹ ๋ฌธ์„œ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉฐ ๋”ฐ๋ผํ•˜๋˜ ์ค‘ Cannot find a matching credentail ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.

์–ด๋–ค ๋ฌธ์ œ์ธ๊ฐ€ ๊ฒ€์ƒ‰ํ•˜๋˜ ์ค‘ ๋‹ต์„ ์ฐพ์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

Screenshot 2024-11-12 at 10 55 42โ€ฏPM

๋”ฐ๋ผํ•œ ์œ„์˜ ๊ณต์‹ ๋ฌธ์„œ ์ฝ”๋“œ ์ค‘ setFilterByAuthorizedAccounts(true) ๋ถ€๋ถ„์—์„œ ์—๋Ÿฌ๊ฐ€ ๋‚œ ๊ฒƒ์ด์—ˆ๋‹ค.

ํ•ด๋‹น ํ•จ์ˆ˜์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ true ๋กœ ์„ค์ •ํ•˜๋Š” ๊ฒฝ์šฐ, ์•ฑ์— ์ด๋ฏธ ์ธ์ฆ๋œ, ์ด์ „์— ๋กœ๊ทธ์ธํ•œ ๊ตฌ๊ธ€ ๊ณ„์ •๋งŒ ๋กœ๊ทธ์ธํ•  ์ˆ˜ ์žˆ์–ด, ํ•œ๋ฒˆ๋„ ์ธ์ฆํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์— ์œ„์™€ ๊ฐ™์€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์ด์—ˆ๋‹ค.

๋ฐ˜๋ฉด์—, false ๋กœ ์„ค์ •ํ•  ๊ฒฝ์šฐ, ์ƒˆ๋กœ์šด ๊ตฌ๊ธ€ ๊ณ„์ •๋„ ์•ฑ์— ๋กœ๊ทธ์ธํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ฐธ๊ณ 

https://stackoverflow.com/questions/61768804/getting-16-cannot-find-a-matching-credential-when-doing-one-tap-sign-in-and-s

https://developers.google.com/identity/one-tap/android/get-saved-credentials?hl=ko

๐Ÿ’ฅ activity is cancelled by the user

๋ฌธ์ œ ์ •์˜

์œ„์˜ setFilterByAuthorizedAccounts ๊ด€๋ จ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•œ ํ›„ ์‹ค์ œ ๊ตฌ๊ธ€ ๋กœ๊ทธ์ธ ๊ณ„์ •์„ ์„ ํƒํ•˜๊ณ  ๋‚˜์„œ ๋กœ๊ทธ์ธ์ด ์ง„ํ–‰๋˜๋˜ ๋„์ค‘ ์•ฑ์ด ์ข…๋ฃŒ๋˜๊ณ  ์•„๋ž˜์™€ ๊ฐ™์€ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๊ฐ€ ์ถœ๋ ฅ๋˜์—ˆ๋‹ค.

???

๋ฌธ์ œ ํ•ด๊ฒฐ ๊ณผ์ •

https://stackoverflow.com/questions/77717346/androidx-credentials-exceptions-getcredentialcancellationexception-activity-is

https://medium.com/@primo8296/unlocking-doors-harnessing-credential-manager-for-seamless-logins-ebf7a8bcd172

์œ„ ์ฐธ๊ณ  ์ž๋ฃŒ์—์„œ ๋‹ต์„ ์ฐพ์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

My findings says that, if we use OAuth Client ID generated using application type Android, then it will not work and generate this exception

์ฆ‰, GetGoogleIdOption.setServerClientId(key: String) ์—์„œ ํ‚ค ๊ฐ’์œผ๋กœ ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ‚ค ๊ฐ’์„ ๋„ฃ์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

Screenshot 2024-11-12 at 11 10 50โ€ฏPM

์ด์ „์—๋Š” Google Cloud Console์˜ ์œ ํ˜•์—์„œ Android ์œ ํ˜•์˜ ํด๋ผ์ด์–ธํŠธ ID๋ฅผ ์‚ฌ์šฉํ–ˆ์—ˆ๋Š”๋ฐ, ์ด๊ฒƒ์„ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํด๋ผ์ด์–ธํŠธ ID๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค๋Š” ๊ฒƒ์ด์—ˆ๋‹ค.

Screenshot 2024-11-12 at 11 12 48โ€ฏPM

์ด๋Š” ๊ณต์‹๋ฌธ์„œ์—๋„ ๋‚˜์˜จ ๋‚ด์šฉ์ด๋‹ค.

๊ณต์‹๋ฌธ์„œ๋ฅผ ๊ผผ๊ผผํžˆ ์ฝ์ง€ ์•Š์•˜๊ธฐ์— ๋ฐœ์ƒํ•œ ๋ฌธ์ œ

โš ๏ธ **GitHub.com Fallback** โš ๏ธ