Refactor user and theme management to use BLoC pattern; remove provider classes and integrate new services for user and group functionalities

This commit is contained in:
Dayron
2025-10-14 12:10:42 +02:00
parent c4588a65c0
commit 72ddb58a11
27 changed files with 1864 additions and 791 deletions

View File

@@ -0,0 +1,291 @@
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import '../blocs/user/user_state.dart';
class UserService {
final FirebaseFirestore _firestore;
final FirebaseAuth _auth;
static const String _usersCollection = 'users';
UserService({
FirebaseFirestore? firestore,
FirebaseAuth? auth,
}) : _firestore = firestore ?? FirebaseFirestore.instance,
_auth = auth ?? FirebaseAuth.instance;
// Obtenir l'utilisateur connecté actuel
User? getCurrentFirebaseUser() {
return _auth.currentUser;
}
// Obtenir l'ID de l'utilisateur connecté
String? getCurrentUserId() {
return _auth.currentUser?.uid;
}
// Créer un nouvel utilisateur dans Firestore
Future<bool> createUser(UserModel user) async {
try {
await _firestore
.collection(_usersCollection)
.doc(user.id)
.set(user.toJson());
return true;
} catch (e) {
print('Erreur lors de la création de l\'utilisateur: $e');
return false;
}
}
// Obtenir un utilisateur par son ID
Future<UserModel?> getUserById(String userId) async {
try {
final doc = await _firestore
.collection(_usersCollection)
.doc(userId)
.get();
if (doc.exists) {
return UserModel.fromJson({
'id': doc.id,
...doc.data() as Map<String, dynamic>,
});
}
return null;
} catch (e) {
print('Erreur lors de la récupération de l\'utilisateur: $e');
return null;
}
}
// Obtenir un utilisateur par son email
Future<UserModel?> getUserByEmail(String email) async {
try {
final querySnapshot = await _firestore
.collection(_usersCollection)
.where('email', isEqualTo: email)
.limit(1)
.get();
if (querySnapshot.docs.isNotEmpty) {
final doc = querySnapshot.docs.first;
return UserModel.fromJson({
'id': doc.id,
...doc.data(),
});
}
return null;
} catch (e) {
print('Erreur lors de la récupération de l\'utilisateur par email: $e');
return null;
}
}
// Obtenir l'ID d'un utilisateur par son email
Future<String?> getUserIdByEmail(String email) async {
try {
final querySnapshot = await _firestore
.collection(_usersCollection)
.where('email', isEqualTo: email)
.limit(1)
.get();
if (querySnapshot.docs.isNotEmpty) {
return querySnapshot.docs.first.id;
}
return null;
} catch (e) {
print('Erreur lors de la récupération de l\'ID utilisateur: $e');
return null;
}
}
// Mettre à jour un utilisateur
Future<bool> updateUser(String userId, Map<String, dynamic> userData) async {
try {
await _firestore
.collection(_usersCollection)
.doc(userId)
.update(userData);
return true;
} catch (e) {
print('Erreur lors de la mise à jour de l\'utilisateur: $e');
return false;
}
}
// Supprimer un utilisateur
Future<bool> deleteUser(String userId) async {
try {
await _firestore
.collection(_usersCollection)
.doc(userId)
.delete();
return true;
} catch (e) {
print('Erreur lors de la suppression de l\'utilisateur: $e');
return false;
}
}
// Vérifier si un email existe déjà
Future<bool> emailExists(String email) async {
try {
final querySnapshot = await _firestore
.collection(_usersCollection)
.where('email', isEqualTo: email)
.limit(1)
.get();
return querySnapshot.docs.isNotEmpty;
} catch (e) {
print('Erreur lors de la vérification de l\'email: $e');
return false;
}
}
// Obtenir plusieurs utilisateurs par leurs IDs
Future<List<UserModel>> getUsersByIds(List<String> userIds) async {
try {
if (userIds.isEmpty) return [];
final List<UserModel> users = [];
// Firestore a une limite de 10 éléments pour les requêtes 'in'
// Donc on divise en chunks de 10
for (int i = 0; i < userIds.length; i += 10) {
final chunk = userIds.skip(i).take(10).toList();
final querySnapshot = await _firestore
.collection(_usersCollection)
.where(FieldPath.documentId, whereIn: chunk)
.get();
for (var doc in querySnapshot.docs) {
users.add(UserModel.fromJson({
'id': doc.id,
...doc.data(),
}));
}
}
return users;
} catch (e) {
print('Erreur lors de la récupération des utilisateurs: $e');
return [];
}
}
// Obtenir tous les utilisateurs (à utiliser avec précaution)
Future<List<UserModel>> getAllUsers() async {
try {
final querySnapshot = await _firestore
.collection(_usersCollection)
.get();
return querySnapshot.docs.map((doc) {
return UserModel.fromJson({
'id': doc.id,
...doc.data(),
});
}).toList();
} catch (e) {
print('Erreur lors de la récupération de tous les utilisateurs: $e');
return [];
}
}
// Stream pour écouter les changements d'un utilisateur
Stream<UserModel?> getUserStream(String userId) {
return _firestore
.collection(_usersCollection)
.doc(userId)
.snapshots()
.map((doc) {
if (doc.exists) {
return UserModel.fromJson({
'id': doc.id,
...doc.data() as Map<String, dynamic>,
});
}
return null;
});
}
// Rechercher des utilisateurs par nom ou email
Future<List<UserModel>> searchUsers(String query) async {
try {
if (query.isEmpty) return [];
final queryLower = query.toLowerCase();
// Recherche par email
final emailResults = await _firestore
.collection(_usersCollection)
.where('email', isGreaterThanOrEqualTo: queryLower)
.where('email', isLessThanOrEqualTo: '$queryLower\uf8ff')
.limit(10)
.get();
// Recherche par prénom
final prenomResults = await _firestore
.collection(_usersCollection)
.where('prenom', isGreaterThanOrEqualTo: queryLower)
.where('prenom', isLessThanOrEqualTo: '$queryLower\uf8ff')
.limit(10)
.get();
// Combiner et dédupliquer les résultats
final Map<String, UserModel> usersMap = {};
for (var doc in emailResults.docs) {
usersMap[doc.id] = UserModel.fromJson({
'id': doc.id,
...doc.data(),
});
}
for (var doc in prenomResults.docs) {
usersMap[doc.id] = UserModel.fromJson({
'id': doc.id,
...doc.data(),
});
}
return usersMap.values.toList();
} catch (e) {
print('Erreur lors de la recherche d\'utilisateurs: $e');
return [];
}
}
// Mettre à jour la dernière connexion de l'utilisateur
Future<bool> updateLastLogin(String userId) async {
try {
await _firestore
.collection(_usersCollection)
.doc(userId)
.update({
'lastLogin': FieldValue.serverTimestamp(),
});
return true;
} catch (e) {
print('Erreur lors de la mise à jour de la dernière connexion: $e');
return false;
}
}
// Vérifier si l'utilisateur existe dans Firestore
Future<bool> userExists(String userId) async {
try {
final doc = await _firestore
.collection(_usersCollection)
.doc(userId)
.get();
return doc.exists;
} catch (e) {
print('Erreur lors de la vérification de l\'existence de l\'utilisateur: $e');
return false;
}
}
}