MotorSignal-App/lib/services/auth/auth_providers.dart

95 lines
2.7 KiB
Dart

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<AuthService>((ref) {
final service = FirebaseAuthService();
ref.onDispose(() => service.dispose());
return service;
});
/// Reactive StateNotifier managing the authentication state for the UI
class AuthNotifier extends StateNotifier<AuthState> {
final AuthService _authService;
StreamSubscription<AuthState>? _subscription;
AuthNotifier(this._authService) : super(_authService.currentState) {
_subscription = _authService.authStateChanges.listen((state) {
this.state = state;
});
}
Future<void> signInWithEmailAndPassword(String email, String password) async {
await _authService.signInWithEmailAndPassword(email, password);
state = _authService.currentState;
}
Future<void> createUserWithEmailAndPassword(
String email,
String password, {
String? displayName,
}) async {
await _authService.createUserWithEmailAndPassword(
email,
password,
displayName: displayName,
);
state = _authService.currentState;
}
Future<void> signInWithGoogle() async {
await _authService.signInWithGoogle();
state = _authService.currentState;
}
Future<void> signInAnonymously() async {
await _authService.signInAnonymously();
state = _authService.currentState;
}
Future<void> sendPasswordResetEmail(String email) async {
await _authService.sendPasswordResetEmail(email);
state = _authService.currentState;
}
Future<void> 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<AuthNotifier, AuthState>((ref) {
final service = ref.watch(authServiceProvider);
return AuthNotifier(service);
});
/// Convenience provider returning the active AuthUser or null
final currentUserProvider = Provider<AuthUser?>((ref) {
return ref.watch(authNotifierProvider).user;
});
/// Convenience provider returning whether a non-anonymous user is signed in
final isAuthenticatedProvider = Provider<bool>((ref) {
return ref.watch(authNotifierProvider).isAuthenticated;
});
/// Convenience provider returning whether the user is in anonymous/local mode
final isAnonymousUserProvider = Provider<bool>((ref) {
return ref.watch(authNotifierProvider).isAnonymous;
});