import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; class AuthService { final FirebaseAuth _auth = FirebaseAuth.instance; final FirebaseFirestore _firestore = FirebaseFirestore.instance; final FirebaseMessaging _messaging = FirebaseMessaging.instance; final _storage = const FlutterSecureStorage( aOptions: AndroidOptions( encryptedSharedPreferences: true, resetOnError: true, ), ); Future login({required String email, required String password}) async { try { final cleanEmail = email.trim(); UserCredential userCredential = await _auth.signInWithEmailAndPassword( email: cleanEmail, password: password, ); User? user = userCredential.user; if (user == null) throw 'Login gagal, pengguna tidak ditemukan.'; DocumentSnapshot userDoc = await _firestore.collection('siswa').doc(user.uid).get(); if (!userDoc.exists) { await _auth.signOut(); throw 'Data pengguna tidak ditemukan di database.'; } Map data = userDoc.data() as Map; String role = data['role'] ?? 'unknown'; if (role != 'Orang Tua') { await _auth.signOut(); throw 'Akses ditolak. Akun ini bukan akun Orang Tua.'; } // 1. Ambil FCM Token perangkat baru ini String? fcmToken = await _messaging.getToken(); // 2. Update Token ke Firestore sebagai token aktif tunggal await _firestore.collection('siswa').doc(user.uid).set({ 'fcm_token': fcmToken, 'last_login': FieldValue.serverTimestamp(), }, SetOptions(merge: true)); String? idToken = await user.getIdToken(); // 3. Simpan Session & Token FCM ke Lokal await _storage.write(key: 'access_token', value: idToken); await _storage.write(key: 'uid', value: user.uid); await _storage.write(key: 'role', value: role); if (fcmToken != null) { await _storage.write( key: 'fcm_token', value: fcmToken, ); // Simpan untuk validasi nanti } } on FirebaseAuthException catch (e) { throw _handleFirebaseAuthError(e); } catch (e) { rethrow; } } Future logout() async { await _auth.signOut(); await _storage.deleteAll(); } Future getAccessToken() async => await _storage.read(key: 'access_token'); // Helper untuk mengambil token FCM yang tersimpan di HP ini Future getStoredFcmToken() async => await _storage.read(key: 'fcm_token'); String _handleFirebaseAuthError(FirebaseAuthException e) { switch (e.code) { case 'invalid-credential': return 'Email atau kata sandi salah.'; case 'user-not-found': return 'Email tidak terdaftar.'; case 'too-many-requests': return 'Terlalu banyak percobaan. Silakan coba lagi nanti.'; default: return 'Terjadi kesalahan: ${e.message}'; } } }