Firebase Auth and Bloc Guide
Setting up Firebase Authentication with a centralized service, GetIt for dependency injection, and Flutter Bloc for state management.
Firebase Auth Service Methods
Let’s setup the interface that our implementation class would be using to connect to firebase auth.
Features
- Anonymous Sign In
- Sign in with social providers like Google, Apple.
- Email signIn
- Utility to fetch the user access token
- Utility to fetch the user ID
- Update user profile on firebase user
Example implementation of the firebase
State Management with Bloc
State
In the bloc state we will track whether the user is authenticated on or not. That is the single responsibility of the auth bloc. When the user is signed in you will have access to the user object from the bloc’s state.
Events
The AuthEvent class defines two main events that can be triggered in the authentication flow:
-
signedInWithProvider
: This event is triggered when a user successfully signs in through any authentication provider (Google, Apple, Email, or Anonymous). It carries the Firebase User object which contains the user’s authentication details. When this event is processed, the bloc will transition to thesignedIn
state with the provided user. -
signOut
: This event is triggered when the user wants to sign out of the application. When processed, it will transition the bloc to thesignedOut
state.
These events work in conjunction with the IAuthService
implementation:
- When a user successfully authenticates through any of the service methods (signInWithGoogle, signInWithApple, etc.), the bloc should receive a
signedInWithProvider
event with the authenticated user. - When the user signs out, the bloc should receive a
signOut
event.
The bloc’s state management ensures that the UI always reflects the current authentication status of the user, whether they are signed in (with their user details) or signed out.
Bloc Implementation Code
The AuthBloc
implementation manages the authentication state and handles various authentication-related operations. Here’s a breakdown of its key features:
Initialization and State Management
- The bloc initializes with a
signedOut
state - It sets up a listener for Firebase Auth state changes using
authStateChanges()
- When auth state changes, it automatically dispatches appropriate events:
signOut
when user is nullsignedInWithProvider
when a user is present
Event Handlers
-
Sign Out Handler (
_SignOut
)- Transitions to
signedOut
state - Handles RevenueCat (Purchases) logout if configured and not anonymous
- Cleans up user session
- Transitions to
-
Sign In Handler (
_SignedInWithProvider
)- Transitions to
signedIn
state with the user object - Sets up user tracking across various services:
- Firebase Crashlytics user identifier
- Firebase Analytics user ID
- Facebook App Events user ID
- RevenueCat user login
- Logs user details for debugging
- Transitions to
Utility Methods
getUser()
: Returns the current user if signed in, null otherwiseisLoggedIn()
: Returns a boolean indicating if the user is currently logged inclose()
: Properly cleans up the auth state stream subscription when the bloc is closed
Integration with External Services
The bloc integrates with multiple services to provide a complete authentication solution:
- Firebase Authentication for core auth functionality
- Firebase Analytics for user tracking
- Firebase Crashlytics for error reporting
- Facebook App Events for analytics
- RevenueCat for subscription management
Each integrated service requires a user identifier to function properly. After successful authentication, we associate the user ID with these services to enable features like analytics tracking and purchase monitoring. For instance, when a user makes a purchase or triggers an analytics event, the system needs their ID to properly attribute that activity.
Registering the auth bloc as dependency
Navigation and Authentication Flow
For a comprehensive guide on implementing navigation with authentication in your Flutter app, including route protection, deep linking, and best practices, please refer to our Navigation Guide.
The navigation guide covers:
- Basic navigation setup with GoRouter
- Authentication flow implementation
- Route protection and guards
- State management integration
- Deep linking configuration
- Common navigation patterns
- Troubleshooting common issues