Firebase Authentication Integration in Mobile Applications
Firebase Authentication handles a large volume of work out of the box: Email/Password, Phone, Google, Apple, Facebook, GitHub, anonymous auth — all ready-made providers. But "out of the box" doesn't mean "without configuration." Projects that simply added FirebaseAuth.getInstance() and considered the task solved regularly encounter problems in production.
Most Common Misconfiguration
ID Token vs Custom Token vs Access Token. Firebase Auth returns Firebase ID Token — a JWT signed by Google. This is not an OAuth 2.0 access token for a third-party API. If your backend is not Firebase, you must verify the Firebase ID Token on the server (admin.auth().verifyIdToken()), obtain the UID, and issue your own JWT. I've seen projects where Firebase ID Token was passed directly to a third-party API hoping that "a token exists means authorization." This doesn't work.
Token refresh. Firebase SDK automatically updates ID Token every hour. But currentUser?.getIdToken(forceRefresh: false) returns a cached token that may be 55 minutes from expiry. If you pass the token to backend, call getIdToken(forceRefresh: true) before each request or use Auth.auth().currentUser?.getIDTokenResult() to check expirationDate.
Sign in with Apple — separate configuration. Apple requires passing nonce — a random string whose hash is included in Apple Identity Token. Firebase validates this hash. Without nonce, integration works during development but fails in production on some Apple ID configurations.
// iOS — correct Sign in with Apple + Firebase integration
let nonce = randomNonceString()
currentNonce = nonce
let request = ASAuthorizationAppleIDProvider().createRequest()
request.requestedScopes = [.fullName, .email]
request.nonce = sha256(nonce)
When receiving Apple credential:
let credential = OAuthProvider.appleCredential(
withIDToken: appleIDToken,
rawNonce: nonce, // pass original nonce, not hash
fullName: appleIDCredential.fullName
)
Auth.auth().signIn(with: credential)
Phone Authentication: Nuances
Firebase Phone Auth works via reCAPTCHA verification on iOS and Play Integrity / SafetyNet on Android. Issues:
- On iOS simulator, invisible reCAPTCHA is used automatically — on production on real devices, behavior may differ (challenge appears).
-
verifyPhoneNumberrequiresAPNsconfiguration for silent push on iOS — without this, verification doesn't complete on devices with push notifications. - On Android:
PhoneAuthProvider.verifyPhoneNumberwithPhoneAuthOptions.Builder. UsesetActivity(this)— without binding to Activity, automatic detection doesn't work.
Test phone numbers in Firebase Console (+1 650-555-3434) allow testing without real SMS — add them for QA environment.
Listeners: AuthStateListener and IdTokenChangedListener
Two different listeners — different events:
-
addAuthStateListenertriggers on user login/logout. -
addIdTokenChangedListeneradditionally triggers on each ID Token update (every hour).
For token synchronization with backend, use IdTokenChangedListener. For navigation decisions (show login screen / hide) — AuthStateListener.
On iOS, important to remove listener on dealloc/deinit:
deinit {
if let handle = authStateHandle {
Auth.auth().removeStateDidChangeListener(handle)
}
}
Otherwise, crash when Firebase tries to invoke callback on already deinitialized object.
Security Rules
If using Firestore or Realtime Database, Security Rules must reference request.auth.uid, not trust client-side logic. Typical hole: users collection without read rule — any authenticated user reads any other user's data.
Minimal rule:
match /users/{userId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
Multi-tenancy
Firebase Authentication supports tenants (via Google Cloud Identity Platform — advanced Firebase Auth version). If you have SaaS with isolated clients, this is the right path instead of creating separate Firebase projects. Auth.auth().tenantID = "tenant-xyz" — switches context.
Integration Stages
Create Firebase project and configure providers → add GoogleService-Info.plist / google-services.json → implement auth flow with error handling → configure backend ID Token verification → test email/phone/social providers → Security Rules audit → test on real devices.
Timeline: 6–10 business days for standard provider set (email + google + apple). Each additional social provider (Facebook, Twitter) — plus 1–2 days accounting for developer account configuration.







