firebase-ios-sdk
firebase-ios-sdk copied to clipboard
Add AsyncStream support for Firebase Auth
Fix #15361
To better align the Firebase Auth SDK with modern Swift concurrency, this PR introduces AsyncStream-based APIs for observing authentication state and ID token changes.
Key Features & Benefits
- Modern Concurrency: New
authStateChangesandidTokenChangesproperties onAuthreturn anAsyncStream<User?>, allowing developers to usefor awaitloops to monitor authentication events, which is more idiomatic in modern Swift. - Improved Ergonomics: These new APIs provide a more intuitive and readable alternative to the traditional closure-based listeners (
addStateDidChangeListenerandaddIDTokenDidChangeListener). - Resource Safety: The streams are designed to be safely cancelled, preventing potential resource leaks. This is validated by comprehensive unit tests.
Implementation Details
- The new async properties are housed in a new
FirebaseAuth/Sources/Auth+Async.swiftfile. - Unit tests have been added in
FirebaseAuth/Tests/Unit/AuthAsyncTests.swiftto cover sign-in, sign-out, token refresh, and stream cancellation scenarios. - The
FirebaseAuth/CHANGELOG.mdhas been updated to reflect these new features. - The new APIs are documented with clear usage examples, following Apple's documentation best practices.
Example Usage
Monitoring Authentication State
func monitorAuthState() async {
for await user in Auth.auth().authStateChanges {
if let user = user {
print("User signed in: \(user.uid)")
// Update UI or perform actions for a signed-in user.
} else {
print("User signed out.")
// Update UI or perform actions for a signed-out state.
}
}
}
Monitoring ID Token Changes
func monitorIDTokenState() async {
for await user in Auth.auth().idTokenChanges {
if let user = user {
print("ID token changed for user: \(user.uid)")
// The user's ID token has been refreshed.
// You can get the new token by calling user.getIDToken()
do {
let token = try await user.getIDToken()
print("New ID token: \(token)")
// Send the new token to your backend server, etc.
} catch {
print("Error getting ID token: \(error)")
}
}
}
}