feat: Integrate Firebase Authentication and Firestore

- Added Firebase configuration to Android and iOS projects.
- Created `google-services.json` and `GoogleService-Info.plist` for Firebase setup.
- Implemented `AuthService` for handling user authentication with Firebase.
- Updated `UserProvider` to manage user data with Firestore.
- Refactored `ProfileContent`, `LoginPage`, and `SignUpPage` to use the new authentication service.
- Removed the old `UserService` and replaced it with Firestore-based user management.
- Added Firebase options in `firebase_options.dart` for platform-specific configurations.
- Updated dependencies in `pubspec.yaml` for Firebase packages.
This commit is contained in:
Dayron
2025-10-06 18:57:30 +02:00
parent 0b9a140620
commit ec0bc59a70
16 changed files with 609 additions and 374 deletions

View File

@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import '../services/user_service.dart';
import '../services/auth_service.dart';
import 'package:provider/provider.dart';
import '../providers/user_provider.dart';
@@ -14,7 +14,7 @@ class _LoginPageState extends State<LoginPage> {
final _formKey = GlobalKey<FormState>();
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
final _userService = UserService();
final _authService = AuthService();
bool _isLoading = false;
bool _obscurePassword = true;
@@ -26,26 +26,6 @@ class _LoginPageState extends State<LoginPage> {
super.dispose();
}
// Validation de l'email
String? _validateEmail(String? value) {
if (value == null || value.trim().isEmpty) {
return 'Email requis';
}
final emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');
if (!emailRegex.hasMatch(value.trim())) {
return 'Email invalide';
}
return null;
}
// Validation du mot de passe
String? _validatePassword(String? value) {
if (value == null || value.isEmpty) {
return 'Mot de passe requis';
}
return null;
}
// Méthode de connexion
Future<void> _login() async {
if (!_formKey.currentState!.validate()) {
@@ -57,24 +37,26 @@ class _LoginPageState extends State<LoginPage> {
});
try {
final user = await _userService.authenticateUser(
_emailController.text.trim(),
_passwordController.text,
final userCredential = await _authService.signIn(
email: _emailController.text.trim(),
password: _passwordController.text,
);
if (mounted) {
if (user != null) {
// Naviguer vers la page d'accueil
Provider.of<UserProvider>(context, listen: false).setCurrentUser(user);
if (mounted && userCredential.user != null) {
// Récupérer les données utilisateur depuis Firestore
final userProvider = Provider.of<UserProvider>(context, listen: false);
final userData = await userProvider.getUserData(userCredential.user!.uid);
if (userData != null) {
userProvider.setCurrentUser(userData);
Navigator.pushReplacementNamed(context, '/home');
} else {
// Échec de la connexion
_showErrorMessage('Email ou mot de passe incorrect');
_showErrorMessage('Données utilisateur non trouvées');
}
}
} catch (e) {
if (mounted) {
_showErrorMessage('Erreur lors de la connexion: ${e.toString()}');
_showErrorMessage('Email ou mot de passe incorrect');
}
} finally {
if (mounted) {
@@ -85,18 +67,6 @@ class _LoginPageState extends State<LoginPage> {
}
}
void _showErrorMessage(String message) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(message),
backgroundColor: Colors.red,
duration: const Duration(seconds: 3),
),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
@@ -341,4 +311,36 @@ class _LoginPageState extends State<LoginPage> {
),
);
}
// Validation de l'email
String? _validateEmail(String? value) {
if (value == null || value.trim().isEmpty) {
return 'Email requis';
}
final emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');
if (!emailRegex.hasMatch(value.trim())) {
return 'Email invalide';
}
return null;
}
// Validation du mot de passe
String? _validatePassword(String? value) {
if (value == null || value.isEmpty) {
return 'Mot de passe requis';
}
return null;
}
void _showErrorMessage(String message) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(message),
backgroundColor: Colors.red,
duration: const Duration(seconds: 3),
),
);
}
}
}

View File

@@ -1,7 +1,8 @@
import 'package:flutter/material.dart';
import 'package:bcrypt/bcrypt.dart';
import 'package:provider/provider.dart';
import '../models/user.dart';
import '../services/user_service.dart';
import '../services/auth_service.dart';
import '../providers/user_provider.dart';
class SignUpPage extends StatefulWidget {
const SignUpPage({super.key});
@@ -17,7 +18,7 @@ class _SignUpPageState extends State<SignUpPage> {
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
final _confirmPasswordController = TextEditingController();
final _userService = UserService();
final _authService = AuthService();
bool _isLoading = false;
bool _obscurePassword = true;
@@ -84,39 +85,29 @@ class _SignUpPageState extends State<SignUpPage> {
});
try {
// Vérifier si l'email existe déjà
bool emailExists = await _userService.emailExists(
_emailController.text.trim(),
);
if (emailExists) {
_showErrorDialog('Cet email est déjà utilisé');
return;
}
// Hasher le mot de passe
String hashedPassword = BCrypt.hashpw(
_passwordController.text,
BCrypt.gensalt(),
// Créer le compte avec Firebase Auth
final userCredential = await _authService.createAccount(
email: _emailController.text.trim(),
password: _passwordController.text,
);
// Créer l'utilisateur
// Créer l'objet User
User newUser = User(
id: userCredential.user!.uid,
nom: _nomController.text.trim(),
prenom: _prenomController.text.trim(),
email: _emailController.text.trim().toLowerCase(),
password: hashedPassword,
email: _emailController.text.trim(),
);
// Sauvegarder l'utilisateur
bool success = await _userService.addUser(newUser);
// Sauvegarder les données utilisateur dans Firestore
await Provider.of<UserProvider>(context, listen: false).saveUserData(newUser);
if (success) {
_showSuccessDialog();
} else {
_showErrorDialog('Erreur lors de la création du compte');
}
// Mettre à jour le displayName
await _authService.updateDisplayName(displayName: newUser.fullName);
_showSuccessDialog();
} catch (e) {
_showErrorDialog('Une erreur est survenue: ${e.toString()}');
_showErrorDialog('Erreur lors de la création du compte: ${e.toString()}');
} finally {
setState(() {
_isLoading = false;
@@ -351,3 +342,4 @@ class _SignUpPageState extends State<SignUpPage> {
);
}
}