Firebase Auth Manager
Manage Firebase Authentication configuration via the Identity Toolkit Admin API v2. No Firebase Console UI needed.
Prerequisites
gcloudCLI authenticated (gcloud auth login)- Editor/Owner role on the Firebase project
- Know your Firebase Project ID
- Billing must be linked to the GCP project (required for Identity Platform initialization)
First-Time Initialization (CRITICAL)
If the project has never had Firebase Auth enabled, all Admin API v2 calls will return CONFIGURATION_NOT_FOUND. You must initialize Identity Platform first:
Step 1: Enable the Identity Toolkit API
gcloud services enable identitytoolkit.googleapis.com --project=${PROJECT_ID}
Step 2: Ensure Billing is Linked
# Check billing status
gcloud billing projects describe ${PROJECT_ID}
# If billingEnabled: false, link a billing account
gcloud billing accounts list
gcloud billing projects link ${PROJECT_ID} --billing-account=BILLING_ACCOUNT_ID
Note: Firebase billing accounts have a 5-project quota. If quota is exceeded, unlink an unused project first:
gcloud billing projects list --billing-account=BILLING_ACCOUNT_ID gcloud billing projects unlink UNUSED_PROJECT_ID
Step 3: Initialize Identity Platform
curl -s -X POST \
"https://identitytoolkit.googleapis.com/v2/projects/${PROJECT_ID}/identityPlatform:initializeAuth" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "x-goog-user-project: ${PROJECT_ID}" \
-d '{}'
A successful response is {}. After this, all Admin API v2 endpoints will work.
Step 4: Enable Anonymous Auth
curl -s -X PATCH \
"https://identitytoolkit.googleapis.com/admin/v2/projects/${PROJECT_ID}/config?updateMask=signIn.anonymous.enabled" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "x-goog-user-project: ${PROJECT_ID}" \
-d '{"signIn":{"anonymous":{"enabled":true}}}'
API Base
https://identitytoolkit.googleapis.com/admin/v2/projects/{PROJECT_ID}
All requests need:
ACCESS_TOKEN=$(gcloud auth print-access-token)
-H "Authorization: Bearer $ACCESS_TOKEN"
-H "x-goog-user-project: {PROJECT_ID}"
Quick Reference
List All Sign-In Providers
curl -s -X GET \
"https://identitytoolkit.googleapis.com/admin/v2/projects/${PROJECT_ID}/defaultSupportedIdpConfigs" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "x-goog-user-project: ${PROJECT_ID}" | python3 -m json.tool
Enable a Provider
| Provider | idpId | clientId | clientSecret |
|---|---|---|---|
| Apple (iOS-only) | apple.com |
Bundle ID (e.g. com.example.app) |
"" (empty) |
| Apple (cross-platform) | apple.com |
Services ID | Needs Team ID + Key ID + .p8 |
google.com |
OAuth client ID | OAuth client secret | |
| GitHub | github.com |
OAuth App client ID | OAuth App secret |
| Microsoft | microsoft.com |
Azure App client ID | Azure App secret |
Apple (iOS-only):
curl -s -X POST \
"https://identitytoolkit.googleapis.com/admin/v2/projects/${PROJECT_ID}/defaultSupportedIdpConfigs?idpId=apple.com" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "x-goog-user-project: ${PROJECT_ID}" \
-d '{"enabled": true, "clientId": "YOUR_BUNDLE_ID", "clientSecret": ""}'
Google / GitHub / others:
curl -s -X POST \
"https://identitytoolkit.googleapis.com/admin/v2/projects/${PROJECT_ID}/defaultSupportedIdpConfigs?idpId=google.com" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "x-goog-user-project: ${PROJECT_ID}" \
-d '{"enabled": true, "clientId": "CLIENT_ID", "clientSecret": "CLIENT_SECRET"}'
Update a Provider (e.g. change clientId)
curl -s -X PATCH \
"https://identitytoolkit.googleapis.com/admin/v2/projects/${PROJECT_ID}/defaultSupportedIdpConfigs/apple.com?updateMask=clientId" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "x-goog-user-project: ${PROJECT_ID}" \
-d '{"clientId": "NEW_CLIENT_ID"}'
Disable a Provider
curl -s -X PATCH \
"https://identitytoolkit.googleapis.com/admin/v2/projects/${PROJECT_ID}/defaultSupportedIdpConfigs/apple.com?updateMask=enabled" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "x-goog-user-project: ${PROJECT_ID}" \
-d '{"enabled": false}'
Get Auth Config (domains, email settings, MFA)
curl -s -X GET \
"https://identitytoolkit.googleapis.com/admin/v2/projects/${PROJECT_ID}/config" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "x-goog-user-project: ${PROJECT_ID}" | python3 -m json.tool
Add Authorized Domain
curl -s -X PATCH \
"https://identitytoolkit.googleapis.com/admin/v2/projects/${PROJECT_ID}/config?updateMask=authorizedDomains" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "x-goog-user-project: ${PROJECT_ID}" \
-d '{"authorizedDomains": ["localhost", "example.firebaseapp.com", "example.web.app", "yourdomain.com"]}'
Common Mistakes
| Mistake | Fix |
|---|---|
CONFIGURATION_NOT_FOUND |
Firebase Auth not initialized. Follow First-Time Initialization section above |
| 403 quota project error | Add -H "x-goog-user-project: ${PROJECT_ID}" header |
Apple clientId set to Services ID |
iOS-only must use bundle ID, not Services ID. Services ID is for web/Android only |
| Provider already exists (409) | Use PATCH to update instead of POST to create |
| Wrong gcloud account | gcloud auth list to check, gcloud config set account EMAIL to switch |
BILLING_NOT_ENABLED on initializeAuth |
Link a billing account to the project first |
Google clientId: "auto" causes Error code:40 |
When using signInWithCredential (not signInWithProvider), the Google provider MUST have the actual Web OAuth client ID, not "auto". Use PATCH with updateMask=clientId to set it. Find the Web client ID in google-services.json → oauth_client → client_type: 3 entry. |
Apple Sign-In: iOS-only vs Cross-Platform
| Config | iOS-only | Cross-platform (iOS + Web/Android) |
|---|---|---|
clientId |
Bundle ID (com.example.app) |
Services ID (com.example.app.service) |
clientSecret |
"" (empty) |
JWT from .p8 key |
| Team ID / Key ID / .p8 | Not needed | Required |
| Apple Services ID | Not needed | Must create in Apple Developer Console |
| Callback URL | Not needed | https://{project}.firebaseapp.com/__/auth/handler |
Apple Sign-In Checklist (iOS)
- Firebase: Enable
apple.comprovider withclientId= bundle ID (this skill) - Apple Developer Console: App ID has "Sign in with Apple" capability
- Xcode:
Runner.entitlementshascom.apple.developer.applesignin - Provisioning Profile: Regenerated after adding capability
- Flutter code:
OAuthProvider('apple.com').credential()must include both:idToken: appleCredential.identityTokenrawNonce: rawNonceaccessToken: appleCredential.authorizationCode(CRITICAL - without this →invalid-credential)
Android Google Sign-In Setup (SHA-1 + OAuth)
CRITICAL: Android Google Sign-In (including
google_sign_inv7+ with Credential Manager) requires SHA-1 fingerprints registered in Firebase AND matching OAuth clients ingoogle-services.json. Missing any SHA-1 causes silent failures.
Required SHA-1 Fingerprints (ALL THREE)
| SHA-1 Source | How to Get | When Used |
|---|---|---|
| Debug keystore | keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android |
flutter run / debug builds |
| Release keystore (upload key) | keytool -list -v -keystore /path/to/release.jks -alias YOUR_ALIAS |
Locally signed release builds |
| Play Store App Signing Key | Play Console → App Integrity → App signing key certificate → SHA-1 | APKs downloaded from Play Store |
Most common mistake: Only registering the debug SHA-1, then Google Sign-In fails for Play Store builds. The Play Store re-signs your AAB with Google's own key, so Firebase must know that key's SHA-1 too.
Firebase CLI Commands
# Set variables
APP_ID="1:XXXXXXXXXX:android:YYYYYYYY"
PROJECT="your-project-id"
# 1. Add SHA-1 fingerprints (repeat for each SHA-1)
firebase apps:android:sha:create $APP_ID <SHA1_HEX_NO_COLONS> --project $PROJECT
# 2. List all registered SHA-1s
firebase apps:android:sha:list $APP_ID --project $PROJECT
# 3. Download updated google-services.json
firebase apps:sdkconfig ANDROID $APP_ID --project $PROJECT
# 4. Copy output JSON to android/app/google-services.json
IMPORTANT: After adding SHA-1 via CLI, you MUST re-download
google-services.json— Firebase auto-creates new OAuth clients for each SHA-1, and these must be in the config file.
google-services.json Structure for Google Sign-In
{
"client": [{
"oauth_client": [
{
"client_id": "...-debug.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "com.example.app",
"certificate_hash": "<debug_sha1_lowercase_no_colons>"
}
},
{
"client_id": "...-release.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "com.example.app",
"certificate_hash": "<release_sha1_lowercase_no_colons>"
}
},
{
"client_id": "...-playstore.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "com.example.app",
"certificate_hash": "<playstore_signing_sha1_lowercase_no_colons>"
}
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "...-web.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}]
}
Key fields:
oauth_clientwithclient_type: 1= Android OAuth clients (one per SHA-1)other_platform_oauth_clientwithclient_type: 3= Web client → becomesdefault_web_client_id→ used asserverClientId- If
oauth_clientis[](empty), Google Sign-In will silently fail (appears as "user cancelled")
Play Store App Signing Key SHA-1
The Play Store App Signing Key SHA-1 is NOT available via Google Play Developer API. You must get it from the Play Console UI:
- Navigate to:
https://play.google.com/console/u/0/developers/<DEV_ID>/app/<APP_ID>/keymanagement - Or: Play Console → your app → Setup → App Integrity → App signing
- Copy the SHA-1 certificate fingerprint under "App signing key certificate"
- NOT the one under "Upload key certificate" (that's your release keystore)
Debugging Android Google Sign-In
| Symptom | Root Cause | Fix |
|---|---|---|
CredManProvService: GetCredentialResponse error caught as "user cancelled" |
SHA-1 mismatch — no matching OAuth client for the signing key | Register ALL 3 SHA-1s in Firebase, re-download google-services.json |
oauth_client: [] in google-services.json |
No SHA-1 fingerprints registered for this Android app | Add SHA-1 via firebase apps:android:sha:create |
| Works in debug, fails in release | Release keystore SHA-1 not registered | Add release keystore SHA-1 |
| Works locally, fails from Play Store | Play Store App Signing Key SHA-1 not registered | Get from Play Console App Signing page, add to Firebase |
serverClientId must be provided |
Missing other_platform_oauth_client with client_type: 3 |
Ensure Web client exists in GCP credentials |
Error code 10 / DEVELOPER_ERROR |
SHA-1 mismatch (legacy google_sign_in) | Same fix — register all SHA-1s |
Android Google Sign-In Checklist
- Firebase Console/CLI: Register ALL 3 SHA-1 fingerprints (debug, release, Play Store signing)
- google-services.json: Re-download after adding SHA-1s, verify
oauth_clientis NOT empty - GCP Console: Ensure Web OAuth client exists (auto-created, provides
serverClientId) - Flutter code:
serverClientIdshould match theclient_type: 3client ID - Rebuild app:
flutter clean && flutter run— google-services.json is baked into the build - Support email: Set in Firebase Console → Project Settings → General (required for Google Sign-In)
Debugging invalid-credential
[firebase_auth/invalid-credential] Invalid OAuth response from apple.com:
- Missing
accessToken: Firebase needsauthorizationCodefrom Apple. Pass it asaccessTokeninOAuthProvider.credential() - Wrong
clientId: iOS tokens haveaud= bundle ID. If FirebaseclientIdis Services ID, audience won't match - Provider not enabled: Verify with List Providers API above
Related skills
firebase-flutter-setup— initialize Firebase services first. Firebase-auth-manager builds the sign-in UX on top.flutter-verify— after implementing auth, verify sign-in flows work end-to-end on real devices (email/password, social login, token refresh).