Google 로그인 오류 10과 28444 해결: Developer console is not set up correctly
옛 Google 로그인 SDK의 ApiException: 10과 Credential Manager의 [28444] Developer console is not set up correctly는 같은 설정 문제입니다. 로그인을 요청한 앱(패키지 이름과 이 빌드에 서명한 인증서의 SHA-1)이나 앱이 넘긴 웹 클라이언트 ID가 프로젝트에 등록된 값과 맞지 않는다는 뜻입니다. 코드가 아니라 등록값을 고치면 됩니다. 먼저 지금 실행 중인 빌드에 서명한 키의 SHA-1이 Firebase에 있는지 확인하세요.
요약
- 이름만 다른 같은 오류입니다. 10은 옛 SDK의
DEVELOPER_ERROR이고, 28444는 Credential Manager가 돌려주는 같은 뜻의 메시지입니다. 원인은 패키지 이름, 서명 SHA-1, 웹 클라이언트 ID 중 하나입니다. 오류 구별 - 실행 중인 빌드에 서명한 키의 SHA-1을 등록합니다. 디버그 키, 업로드 키, Google Play의 앱 서명 키는 모두 다릅니다. 빌드별 SHA-1
serverClientId에는 웹 클라이언트 ID를 넣습니다. Android 클라이언트 ID가 아닙니다. 넣을 값- 옛 SDK는 2026년 8월에 제거됐습니다. Credential Manager에서는 같은 설정 오류가 사용자의 취소처럼 보이기도 합니다. 옮길 때
오류 구별
| 오류 | 나오는 곳 | 뜻 |
|---|---|---|
ApiException: 10 | 옛 Google Sign-In for Android | DEVELOPER_ERROR. 앱 설정이 잘못됐습니다. |
[28444] Developer console is not set up correctly. | Credential Manager. Flutter google_sign_in 7에서는 GoogleSignInExceptionCode.unknownError | 문서에 없는 코드입니다. 메시지대로 OAuth 설정이 앱과 맞지 않습니다. |
| 누르지 않았는데 취소됨 | Credential Manager(GetCredentialCancellationException, Flutter canceled) | 설정 오류가 취소로 보고되기도 합니다. |
ApiException: 12500 | 옛 Google Sign-In for Android | Firebase 문서에 따르면 지원 이메일을 넣지 않았거나 SHA 키가 빠졌습니다. |
NoCredentialException | Credential Manager | 설정 문제가 아닙니다. 기기에 Google 계정이 없거나, 이 앱에 로그인한 적 있는 계정만 보여 주는 설정입니다(아래). |
앞의 세 가지는 원인이 같습니다. Flutter 플러그인 문서(google_sign_in_android)는 설정 오류의 흔한 원인으로 빌드의 서명 SHA 누락이나 오류, 서버 쪽에 등록한 패키지 이름 오류, serverClientId 누락이나 오류를 꼽습니다. 이 순서대로 확인하세요.
이 빌드에 서명한 키의 SHA-1
Google은 로그인을 요청한 앱을 패키지 이름과 APK에 서명한 인증서의 SHA-1로 알아봅니다. 패키지 이름은 build.gradle의 applicationId(빌드 타입에 붙인 접미사 포함)이고, Firebase에 등록한 Android 앱의 것과 같아야 합니다. 서명은 앱을 어떻게 설치했느냐에 따라 다릅니다.
| 설치한 빌드 | 서명한 키 | SHA-1 확인 |
|---|---|---|
| Android Studio에서 실행한 디버그 빌드 | 이 컴퓨터의 디버그 키스토어(컴퓨터마다 다름) | signingReport의 debug 항목 |
| 직접 서명해 설치한 릴리스 빌드 | 내 업로드(릴리스) 키 | signingReport의 release 항목 |
| Google Play에서 받은 앱(모든 트랙) | Google이 가진 앱 서명 키 | Play Console의 Play 앱 서명 관리(Manage Play app signing) 페이지 |
| 내부 앱 공유(Internal app sharing)로 받은 앱 | Play의 내부 테스트 인증서 | Play Console의 내부 앱 공유 페이지, 내부 테스트 인증서(Internal test certificate) |
# Every build variant's signing key, from the project root
./gradlew signingReport
# The debug keystore (password: android)
keytool -list -v -alias androiddebugkey -keystore ~/.android/debug.keystore
# The certificate that signed an APK or AAB you already have
keytool -printcert -jarfile app-release.aab찾은 SHA-1을 Firebase 콘솔의 프로젝트 설정(Project settings) > 일반(General) > 내 앱(Your apps)에서 Android 앱의 SHA 인증서 지문(SHA certificate fingerprints)에 추가하고, google-services.json을 다시 받아 교체합니다. Firebase가 그 지문의 Android OAuth 클라이언트를 만들어 줍니다. 쓰는 키를 모두 등록해 두면 어떤 경로로 설치해도 로그인됩니다.
- 직접 설치하면 되는데 Play에서 받으면 실패한다면 앱 서명 키가 빠진 것입니다. Play는 업로드 키가 아니라 Google이 가진 앱 서명 키로 다시 서명합니다.
- 새로 만든 앱은 기본적으로 Play가 키 세 개로 서명합니다(quantum-ready 서명). 이때 Play Console 도움말은 지문 셋을 모두 API 제공자에 등록하라고 안내합니다.
- 같은 패키지 이름과 SHA-1 쌍은 모든 Firebase·Google Cloud 프로젝트를 통틀어 한 곳에만 등록할 수 있습니다. 개발용과 운영용 프로젝트를 나눠 쓴다면 빌드마다 패키지 이름을 다르게 두세요.
serverClientId에는 웹 클라이언트 ID
serverClientId에는 Google Cloud 프로젝트의 웹 애플리케이션 OAuth 클라이언트 ID를 넣습니다. Google ID 토큰의 수신자(audience)로 쓰이는 값이라 Android 클라이언트 ID를 넣으면 안 됩니다. Firebase 프로젝트라면 google-services.json에서 client_type이 3인 항목이고, google-services 플러그인이 R.string.default_web_client_id로 만들어 줍니다.
// Android (Kotlin): the Sign in with Google button
val buttonOption = GetSignInWithGoogleOption.Builder(
serverClientId = getString(R.string.default_web_client_id),
).build()
// Android (Kotlin): the bottom sheet, offering every account on the device
val sheetOption = GetGoogleIdOption.Builder()
.setServerClientId(getString(R.string.default_web_client_id))
.setFilterByAuthorizedAccounts(false)
.build()
// Flutter (google_sign_in 7), without google-services.json
await GoogleSignIn.instance.initialize(
serverClientId: 'YOUR_WEB_CLIENT_ID.apps.googleusercontent.com',
);- Flutter
google_sign_in7은google-services.json에 웹 클라이언트 항목이 있으면serverClientId없이도 그 값을 읽습니다. 항목이 없다면 Firebase 프로젝트에 웹 앱을 추가하고 파일을 다시 받으세요. Android에서는clientId를 쓰지 않습니다. - 6.x에서 7로 올린 뒤 28444가 처음 나왔다면
serverClientId를 의심하세요. Flutter 팀은 6.x가 쓰던 옛 SDK가 이 값을 늘 검사하지는 않아서, 잘못된 값으로도 동작했을 수 있다고 설명합니다(flutter/flutter #174319).
옛 SDK에서 Credential Manager로 옮길 때
옛 Google Sign-In for Android의 API는 play-services-auth 22.0.0(2026년 8월 26일)에서 제거됐습니다. 이 버전 이상을 쓰면 GoogleSignInClient로 짠 로그인 코드는 컴파일되지 않으니 Credential Manager로 옮기세요.
| 옛 SDK | Credential Manager |
|---|---|
GoogleSignInClient의 로그인 화면 | GetSignInWithGoogleOption(버튼) 또는 GetGoogleIdOption(하단 시트) |
silentSignIn() | GetGoogleIdOption에 setFilterByAuthorizedAccounts(true), setAutoSelectEnabled(true) |
requestIdToken(webClientId) | serverClientId에 같은 웹 클라이언트 ID |
signOut() | clearCredentialState() |
ApiException: 10 | [28444] Developer console is not set up correctly 또는 취소 |
setFilterByAuthorizedAccounts의 기본값은true입니다. 이 앱에 로그인한 적 없는 사용자에게는NoCredentialException이 나니, 가입과 첫 로그인에는false로 두거나 버튼 흐름을 쓰세요.- 에뮬레이터에서는 Google 계정에 로그인해 둡니다. Google APIs가 들어간 시스템 이미지를 쓰세요. 기기에 계정이 없으면
NoCredentialException이 납니다.
출처
- CommonStatusCodes.DEVELOPER_ERROR, Play 서비스 출시 노트: 10의 뜻, Google Sign-In API 제거
- 옛 Google Sign-In에서 옮기기, Credential Manager로 Sign in with Google 구현, Credential Manager 문제 해결
- Android에서 Google로 인증(Firebase), Firebase Android 문제 해결 FAQ, google-services 플러그인, SHA 지문과 OAuth 클라이언트(Firebase 도움말)
- OAuth 클라이언트(Google Cloud 도움말), SHA-1 확인, Play 앱 서명, 내부 앱 공유
- google_sign_in_android, flutter/flutter #174319(28444 보고), Sign in with Google Codelab
