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

@@ -0,0 +1,68 @@
import 'package:firebase_auth/firebase_auth.dart';
class AuthService {
final FirebaseAuth firebaseAuth = FirebaseAuth.instance;
User? get currentUser => firebaseAuth.currentUser;
Stream<User?> get authStateChanges => firebaseAuth.authStateChanges();
Future<UserCredential> signIn({
required String email,
required String password
}) async {
return await firebaseAuth.signInWithEmailAndPassword(
email: email, password: password);
}
Future<UserCredential> createAccount({
required String email,
required String password
}) async {
return await firebaseAuth.createUserWithEmailAndPassword(
email: email, password: password);
}
Future<void> signOut() async {
await firebaseAuth.signOut();
}
Future<void> resetPassword(String email) async {
await firebaseAuth.sendPasswordResetEmail(email: email);
}
Future<void> updateDisplayName({
required String displayName,
}) async {
await currentUser!.updateDisplayName(displayName);
}
Future<void> deleteAccount({
required String password,
required String email,
}) async {
// Re-authenticate the user
AuthCredential credential =
EmailAuthProvider.credential(email: email, password: password);
await currentUser!.reauthenticateWithCredential(credential);
// Delete the user
await currentUser!.delete();
await firebaseAuth.signOut();
}
Future<void> resetPasswordFromCurrentPassword({
required String currentPassword,
required String newPassword,
required String email,
}) async {
// Re-authenticate the user
AuthCredential credential =
EmailAuthProvider.credential(email: email, password: currentPassword);
await currentUser!.reauthenticateWithCredential(credential);
// Update the password
await currentUser!.updatePassword(newPassword);
}
}

View File

@@ -1,272 +0,0 @@
import 'dart:io';
import 'dart:convert';
import 'package:path_provider/path_provider.dart';
import 'package:bcrypt/bcrypt.dart';
import '../models/user.dart';
class UserService {
static const String _fileName = 'users.json';
// Obtenir le fichier JSON
Future<File> _getUserFile() async {
final directory = await getApplicationDocumentsDirectory();
return File('${directory.path}/$_fileName');
}
// Charger tous les utilisateurs
Future<List<User>> loadUsers() async {
try {
final file = await _getUserFile();
if (!await file.exists()) return [];
final contents = await file.readAsString();
if (contents.isEmpty) return [];
final List<dynamic> jsonList = json.decode(contents);
return jsonList.map((json) => User.fromMap(json)).toList();
} catch (e) {
//print('Erreur lors du chargement des utilisateurs: $e');
return [];
}
}
// Sauvegarder tous les utilisateurs
Future<void> saveUsers(List<User> users) async {
try {
final file = await _getUserFile();
final jsonList = users.map((user) => user.toMap()).toList();
await file.writeAsString(json.encode(jsonList));
} catch (e) {
//print('Erreur lors de la sauvegarde des utilisateurs: $e');
throw Exception('Erreur de sauvegarde');
}
}
// Ajouter un nouvel utilisateur
Future<bool> addUser(User user) async {
try {
final users = await loadUsers();
// Vérifier si l'email existe déjà
if (users.any((u) => u.email.toLowerCase() == user.email.toLowerCase())) {
return false; // Email déjà utilisé
}
// Générer un ID unique
final newUser = user.copyWith(
id: DateTime.now().millisecondsSinceEpoch.toString(),
);
users.add(newUser);
await saveUsers(users);
return true;
} catch (e) {
//print('Erreur lors de l\'ajout de l\'utilisateur: $e');
return false;
}
}
// Authentifier un utilisateur avec bcrypt
Future<User?> authenticateUser(String email, String password) async {
try {
final users = await loadUsers();
// Trouver l'utilisateur par email (insensible à la casse)
User? user;
try {
user = users.firstWhere(
(u) => u.email.toLowerCase() == email.toLowerCase(),
);
} catch (e) {
return null; // Utilisateur non trouvé
}
// Vérifier le mot de passe avec bcrypt
if (BCrypt.checkpw(password, user.password)) {
return user;
}
return null; // Mot de passe incorrect
} catch (e) {
//print('Erreur lors de l\'authentification: $e');
return null;
}
}
// Vérifier si un email existe
Future<bool> emailExists(String email) async {
try {
final users = await loadUsers();
return users.any(
(user) => user.email.toLowerCase() == email.toLowerCase(),
);
} catch (e) {
//print('Erreur lors de la vérification de l\'email: $e');
return false;
}
}
// Obtenir un utilisateur par ID
Future<User?> getUserById(String id) async {
try {
final users = await loadUsers();
return users.firstWhere((user) => user.id == id);
} catch (e) {
//print('Utilisateur avec l\'ID $id non trouvé');
return null;
}
}
// Obtenir un utilisateur par email
Future<User?> getUserByEmail(String email) async {
try {
final users = await loadUsers();
return users.firstWhere(
(user) => user.email.toLowerCase() == email.toLowerCase(),
);
} catch (e) {
//print('Utilisateur avec l\'email $email non trouvé');
return null;
}
}
// Mettre à jour un utilisateur
Future<bool> updateUser(User updatedUser) async {
try {
final users = await loadUsers();
final index = users.indexWhere((user) => user.id == updatedUser.id);
if (index != -1) {
users[index] = updatedUser;
await saveUsers(users);
return true;
}
return false; // Utilisateur non trouvé
} catch (e) {
//print('Erreur lors de la mise à jour de l\'utilisateur: $e');
return false;
}
}
// Supprimer un utilisateur
Future<bool> deleteUser(String id) async {
try {
final users = await loadUsers();
final initialLength = users.length;
users.removeWhere((user) => user.id == id);
if (users.length < initialLength) {
await saveUsers(users);
return true;
}
return false; // Utilisateur non trouvé
} catch (e) {
//print('Erreur lors de la suppression de l\'utilisateur: $e');
return false;
}
}
// Changer le mot de passe d'un utilisateur
Future<bool> changePassword(
String userId,
String oldPassword,
String newPassword,
) async {
try {
final users = await loadUsers();
final userIndex = users.indexWhere((user) => user.id == userId);
if (userIndex == -1) return false; // Utilisateur non trouvé
final user = users[userIndex];
// Vérifier l'ancien mot de passe
if (!BCrypt.checkpw(oldPassword, user.password)) {
return false; // Ancien mot de passe incorrect
}
// Hasher le nouveau mot de passe
final hashedNewPassword = BCrypt.hashpw(newPassword, BCrypt.gensalt());
// Mettre à jour l'utilisateur
users[userIndex] = user.copyWith(password: hashedNewPassword);
await saveUsers(users);
return true;
} catch (e) {
//print('Erreur lors du changement de mot de passe: $e');
return false;
}
}
// Réinitialiser le mot de passe (pour la fonctionnalité "mot de passe oublié")
Future<bool> resetPassword(String email, String newPassword) async {
try {
final users = await loadUsers();
final userIndex = users.indexWhere(
(user) => user.email.toLowerCase() == email.toLowerCase(),
);
if (userIndex == -1) return false; // Utilisateur non trouvé
// Hasher le nouveau mot de passe
final hashedNewPassword = BCrypt.hashpw(newPassword, BCrypt.gensalt());
// Mettre à jour l'utilisateur
users[userIndex] = users[userIndex].copyWith(password: hashedNewPassword);
await saveUsers(users);
return true;
} catch (e) {
//print('Erreur lors de la réinitialisation du mot de passe: $e');
return false;
}
}
// Obtenir le nombre total d'utilisateurs
Future<int> getUserCount() async {
try {
final users = await loadUsers();
return users.length;
} catch (e) {
//print('Erreur lors du comptage des utilisateurs: $e');
return 0;
}
}
// Vider la base de données (utile pour les tests)
Future<void> clearAllUsers() async {
try {
await saveUsers([]);
} catch (e) {
//print('Erreur lors du vidage de la base de données: $e');
}
}
// Méthode pour créer des utilisateurs de test
Future<void> createTestUsers() async {
try {
final testUsers = [
User(
nom: 'Dupont',
prenom: 'Jean',
email: 'jean.dupont@test.com',
password: BCrypt.hashpw('password123', BCrypt.gensalt()),
),
User(
nom: 'Martin',
prenom: 'Marie',
email: 'marie.martin@test.com',
password: BCrypt.hashpw('password123', BCrypt.gensalt()),
),
];
for (final user in testUsers) {
await addUser(user);
}
} catch (e) {
//print('Erreur lors de la création des utilisateurs de test: $e');
}
}
}