Files

2.4 KiB
Raw Permalink Blame History

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 @State in the App root.
  • SAFE PATTERN: Initialize Auth.auth() lazily (lazy var auth = Auth.auth()) OR explicitly initialize the manager after FirebaseApp.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 any Auth.auth() methods, otherwise your app will crash. Do not initialize Auth objects in SwiftUI @State properties at the App root level.

import FirebaseAuth

2. 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)")
}