@@ -261,22 +261,27 @@ class ForgotPasswordView extends StatelessWidget {
261261
262262 const SizedBox (height: 10 ),
263263
264- // --- BOTÓN PARA BORRAR ALL
264+ // ==========================================================
265+ // === BOTÓN: BORRADO DE LA BASE DE DATOS SOLO ALUMNOS ===
266+ // ==========================================================
265267 TextButton (
266268 onPressed: () async {
267269 final confirm = await showDialog <bool >(
268270 context: context,
269271 builder: (context) => AlertDialog (
270- title: const Text ("⚠️ PELIGRO: BORRAR TODO " ),
272+ title: const Text ("⚠️ ELIMINAR ALUMNOS " ),
271273 content: const Text (
272- "¿Estás seguro? Esto eliminará TODOS los usuarios permanentemente." ),
274+ "Se eliminarán SOLO los usuarios con rol 'student'.\n\n "
275+ "• Jefes de Academia: SE CONSERVAN\n "
276+ "• Admin Tutorías: SE CONSERVA\n "
277+ "• Auth: Se intentará borrar la cuenta si la contraseña es 'alumno123'." ),
273278 actions: [
274279 TextButton (
275280 onPressed: () => Navigator .pop (context, false ),
276281 child: const Text ("CANCELAR" )),
277282 TextButton (
278283 onPressed: () => Navigator .pop (context, true ),
279- child: const Text ("SÍ, BORRAR TODO " ,
284+ child: const Text ("SÍ, BORRAR ALUMNOS " ,
280285 style: TextStyle (
281286 color: Colors .red,
282287 fontWeight: FontWeight .bold))),
@@ -285,57 +290,126 @@ class ForgotPasswordView extends StatelessWidget {
285290 );
286291
287292 if (confirm != true ) return ;
288-
289293 if (! context.mounted) return ;
294+
290295 ScaffoldMessenger .of (context).showSnackBar (
291296 const SnackBar (
292- content: Text ("Eliminando todos los usuarios ..." ),
297+ content: Text ("Iniciando limpieza de alumnos ..." ),
293298 duration: Duration (seconds: 5 )),
294299 );
295300
301+ // Inicializamos contadores
302+ int deletedFirestore = 0 ;
303+ int deletedAuth = 0 ;
304+ //int errors = 0;
305+
296306 try {
307+ // 2. Configuración para Auth "Hack" (App Secundaria)
308+ FirebaseApp tempApp = await Firebase .initializeApp (
309+ name: 'DeleteWorkerApp' ,
310+ options: Firebase .app ().options,
311+ );
312+ FirebaseAuth tempAuth = FirebaseAuth .instanceFor (app: tempApp);
297313 final firestore = FirebaseFirestore .instance;
298- final usersRef = firestore.collection ('users' );
299- final snapshot = await usersRef.get ();
314+
315+ // 3. CONSULTA SEGURA: Traer SOLO estudiantes
316+ // Esto garantiza que Jefes y Tutorías ni siquiera se lean.
317+ final snapshot = await firestore
318+ .collection ('users' )
319+ .where ('role' , isEqualTo: 'student' )
320+ .get ();
321+
322+ if (snapshot.docs.isEmpty) {
323+ await tempApp.delete ();
324+ if (context.mounted) {
325+ ScaffoldMessenger .of (context).showSnackBar (
326+ const SnackBar (content: Text ("No hay alumnos para borrar." )));
327+ }
328+ return ;
329+ }
330+
331+ // Preparamos el batch para Firestore
300332 WriteBatch batch = firestore.batch ();
301333 int batchCount = 0 ;
302334
303- if (snapshot.docs.isEmpty) return ;
304-
335+ // 4. Iterar sobre cada alumno encontrado
305336 for (var doc in snapshot.docs) {
337+ final data = doc.data ();
338+ final email = data['email_inst' ] as String ? ;
339+
340+ // --- A. Borrado de Auth (Intento) ---
341+ if (email != null ) {
342+ try {
343+ // Intentamos loguear con la contraseña por defecto de tus seeders
344+ await tempAuth.signInWithEmailAndPassword (
345+ email: email, password: 'alumno123' );
346+
347+ // Si entra, lo borramos
348+ if (tempAuth.currentUser != null ) {
349+ await tempAuth.currentUser! .delete ();
350+ deletedAuth++ ;
351+ debugPrint ("Auth borrado: $email " );
352+ }
353+ } catch (e) {
354+ // Si falla (ej. contraseña cambiada o ya no existe en Auth),
355+ // solo lo logueamos y seguimos con Firestore.
356+ debugPrint ("No se pudo borrar Auth de $email : $e " );
357+ }
358+ }
359+
360+ // --- B. Borrado de Firestore ---
306361 batch.delete (doc.reference);
362+ deletedFirestore++ ;
307363 batchCount++ ;
308- if (batchCount >= 450 ) {
364+
365+ // Commit cada 400 docs para no saturar
366+ if (batchCount >= 400 ) {
309367 await batch.commit ();
310368 batch = firestore.batch ();
311369 batchCount = 0 ;
312370 }
313371 }
372+
373+ // Commit final de los restantes
314374 if (batchCount > 0 ) await batch.commit ();
315375
376+ // Limpieza de la app secundaria
377+ await tempApp.delete ();
378+
379+ // 5. Resultado
316380 if (context.mounted) {
317381 showDialog (
318382 context: context,
319383 builder: (_) => AlertDialog (
320- title: const Text ("🗑️ Limpieza Terminada" ),
321- content:
322- const Text ("Se eliminaron todos los usuarios." ),
384+ title: const Text ("🧹 Limpieza Finalizada" ),
385+ content: Text (
386+ "Resultados:\n\n "
387+ "✅ Alumnos en BD borrados: $deletedFirestore \n "
388+ "✅ Cuentas Auth borradas: $deletedAuth \n "
389+ "🛡️ Jefes y Admins: INTACTOS\n\n "
390+ "Nota: Si 'Cuentas Auth' es menor, es porque esos alumnos cambiaron su contraseña o ya no existían." ),
323391 actions: [
324392 TextButton (
325393 onPressed: () => Navigator .pop (context),
326- child: const Text ("OK " ))
394+ child: const Text ("Perfecto " ))
327395 ],
328396 ),
329397 );
330398 }
399+
331400 } catch (e) {
332- debugPrint (e.toString ());
401+ debugPrint ("Error fatal: $e " );
402+ // Intentar limpiar la app secundaria si falló algo crítico
403+ try { await Firebase .app ('DeleteWorkerApp' ).delete (); } catch (_) {}
404+ if (context.mounted) {
405+ ScaffoldMessenger .of (context).showSnackBar (
406+ SnackBar (content: Text ("Error: $e " )));
407+ }
333408 }
334409 },
335410 child: const Text (
336- "BORRAR BD (DELETE ALL)" ,
337- style:
338- TextStyle (color: Colors .red, fontWeight: FontWeight .bold),
411+ "BORRAR SOLO ALUMNOS" ,
412+ style: TextStyle (color: Colors .redAccent, fontWeight: FontWeight .bold),
339413 ),
340414 ),
341415
0 commit comments