import 'dart:async'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'auth_service.dart'; import 'auth_state.dart'; import 'auth_user.dart'; /// Provider for the underlying AuthService instance. /// Can be overridden in tests with a mock or fake AuthService. final authServiceProvider = Provider((ref) { final service = FirebaseAuthService(); ref.onDispose(() => service.dispose()); return service; }); /// Reactive StateNotifier managing the authentication state for the UI class AuthNotifier extends StateNotifier { final AuthService _authService; StreamSubscription? _subscription; AuthNotifier(this._authService) : super(_authService.currentState) { _subscription = _authService.authStateChanges.listen((state) { this.state = state; }); } Future signInWithEmailAndPassword(String email, String password) async { await _authService.signInWithEmailAndPassword(email, password); state = _authService.currentState; } Future createUserWithEmailAndPassword( String email, String password, { String? displayName, }) async { await _authService.createUserWithEmailAndPassword( email, password, displayName: displayName, ); state = _authService.currentState; } Future signInWithGoogle() async { await _authService.signInWithGoogle(); state = _authService.currentState; } Future signInAnonymously() async { await _authService.signInAnonymously(); state = _authService.currentState; } Future sendPasswordResetEmail(String email) async { await _authService.sendPasswordResetEmail(email); state = _authService.currentState; } Future signOut() async { await _authService.signOut(); state = _authService.currentState; } void clearError() { state = state.copyWith(clearError: true); } @override void dispose() { _subscription?.cancel(); super.dispose(); } } /// Primary Riverpod provider for UI reactivity on authentication final authNotifierProvider = StateNotifierProvider((ref) { final service = ref.watch(authServiceProvider); return AuthNotifier(service); }); /// Convenience provider returning the active AuthUser or null final currentUserProvider = Provider((ref) { return ref.watch(authNotifierProvider).user; }); /// Convenience provider returning whether a non-anonymous user is signed in final isAuthenticatedProvider = Provider((ref) { return ref.watch(authNotifierProvider).isAuthenticated; }); /// Convenience provider returning whether the user is in anonymous/local mode final isAnonymousUserProvider = Provider((ref) { return ref.watch(authNotifierProvider).isAnonymous; });