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:
@@ -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');
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user