Firebase Auth iOS Setup Guide
⛔️ CRITICAL RULE: NO INLINE INITIALIZATION ⛔️
NEVER write let auth = Auth.auth() as an inline class or struct property if
there is ANY chance the object is instantiated before FirebaseApp.configure()
executes in the app root.
- FATAL CRASH:
@Observable class AuthManager { let auth = Auth.auth() }initialized as a@Statein the App root. - SAFE PATTERN: Initialize
Auth.auth()lazily (lazy var auth = Auth.auth()) OR explicitly initialize the manager afterFirebaseApp.configure()finishes.
1. Import and Initialize
Ensure you have installed the FirebaseAuth SDK. Use the xcode-project-setup
skill to automate adding the SPM dependency to the Xcode project.
Note: Ensure
FirebaseApp.configure()has been executed in your app's entry point before calling anyAuth.auth()methods, otherwise your app will crash. Do not initialize Auth objects in SwiftUI@Stateproperties at the App root level.
import FirebaseAuth2. Authentication State
To listen for authentication state changes (recommended way to check if a user is signed in):
var handle: AuthStateDidChangeListenerHandle?
handle = Auth.auth().addStateDidChangeListener { auth, user in
if let user = user {
print("User is signed in with uid: \(user.uid)")
} else {
print("User is signed out")
}
}
// To remove the listener when no longer needed:
if let handle = handle {
Auth.auth().removeStateDidChangeListener(handle)
}3. Email and Password Authentication (Modern Concurrency)
Modern Swift projects should prioritize async/await for authentication calls
to avoid nested completion handlers and improve readability.
Sign Up
do {
let authResult = try await Auth.auth().createUser(withEmail: "user@example.com", password: "password")
print("User created successfully with uid: \(authResult.user.uid)")
} catch {
print("Error creating user: \(error.localizedDescription)")
}Sign In
do {
let authResult = try await Auth.auth().signIn(withEmail: "user@example.com", password: "password")
print("User signed in successfully with uid: \(authResult.user.uid)")
} catch {
print("Error signing in: \(error.localizedDescription)")
}4. Sign Out
do {
try Auth.auth().signOut()
print("Successfully signed out")
} catch let signOutError as NSError {
print("Error signing out: \(signOutError)")
}