210 lines
5.9 KiB
Dart
210 lines
5.9 KiB
Dart
import 'package:cloud_firestore/cloud_firestore.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
class FirestoreService {
|
|
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
|
|
|
|
// Collections
|
|
static const String usersCollection = 'users';
|
|
static const String detectionsCollection = 'detections';
|
|
static const String alertsCollection = 'alerts';
|
|
static const String devicesCollection = 'devices';
|
|
|
|
// User operations
|
|
Future<void> createUserProfile({
|
|
required String uid,
|
|
required String email,
|
|
String? displayName,
|
|
String? photoURL,
|
|
}) async {
|
|
try {
|
|
await _firestore.collection(usersCollection).doc(uid).set({
|
|
'email': email,
|
|
'displayName': displayName ?? '',
|
|
'photoURL': photoURL ?? '',
|
|
'createdAt': FieldValue.serverTimestamp(),
|
|
'updatedAt': FieldValue.serverTimestamp(),
|
|
'role': 'user',
|
|
'isActive': true,
|
|
});
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
print('Create user profile error: $e');
|
|
}
|
|
throw 'Gagal membuat profil pengguna';
|
|
}
|
|
}
|
|
|
|
Future<DocumentSnapshot?> getUserProfile(String uid) async {
|
|
try {
|
|
DocumentSnapshot doc =
|
|
await _firestore.collection(usersCollection).doc(uid).get();
|
|
return doc.exists ? doc : null;
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
print('Get user profile error: $e');
|
|
}
|
|
throw 'Gagal mengambil profil pengguna';
|
|
}
|
|
}
|
|
|
|
Future<void> updateUserProfile({
|
|
required String uid,
|
|
Map<String, dynamic>? data,
|
|
}) async {
|
|
try {
|
|
if (data != null) {
|
|
data['updatedAt'] = FieldValue.serverTimestamp();
|
|
await _firestore.collection(usersCollection).doc(uid).update(data);
|
|
}
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
print('Update user profile error: $e');
|
|
}
|
|
throw 'Gagal mengupdate profil pengguna';
|
|
}
|
|
}
|
|
|
|
// Fire detection operations
|
|
Future<void> saveDetectionData({
|
|
required String uid,
|
|
required Map<String, dynamic> detectionData,
|
|
}) async {
|
|
try {
|
|
await _firestore.collection(detectionsCollection).add({
|
|
'userId': uid,
|
|
'timestamp': FieldValue.serverTimestamp(),
|
|
'location': detectionData['location'] ?? '',
|
|
'confidence': detectionData['confidence'] ?? 0.0,
|
|
'imageUrl': detectionData['imageUrl'] ?? '',
|
|
'status': detectionData['status'] ?? 'detected',
|
|
'severity': detectionData['severity'] ?? 'medium',
|
|
'description': detectionData['description'] ?? '',
|
|
'resolved': false,
|
|
'createdAt': FieldValue.serverTimestamp(),
|
|
});
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
print('Save detection error: $e');
|
|
}
|
|
throw 'Gagal menyimpan data deteksi';
|
|
}
|
|
}
|
|
|
|
Stream<QuerySnapshot> getDetectionHistory(String uid) {
|
|
return _firestore
|
|
.collection(detectionsCollection)
|
|
.where('userId', isEqualTo: uid)
|
|
.orderBy('timestamp', descending: true)
|
|
.snapshots();
|
|
}
|
|
|
|
// Alert operations
|
|
Future<void> createAlert({
|
|
required String uid,
|
|
required String detectionId,
|
|
required Map<String, dynamic> alertData,
|
|
}) async {
|
|
try {
|
|
await _firestore.collection(alertsCollection).add({
|
|
'userId': uid,
|
|
'detectionId': detectionId,
|
|
'title': alertData['title'] ?? 'Fire Detected',
|
|
'message': alertData['message'] ?? 'Kebakaran terdeteksi',
|
|
'severity': alertData['severity'] ?? 'high',
|
|
'location': alertData['location'] ?? '',
|
|
'timestamp': FieldValue.serverTimestamp(),
|
|
'isRead': false,
|
|
'isResolved': false,
|
|
'createdAt': FieldValue.serverTimestamp(),
|
|
});
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
print('Create alert error: $e');
|
|
}
|
|
throw 'Gagal membuat alert';
|
|
}
|
|
}
|
|
|
|
Stream<QuerySnapshot> getAlerts(String uid) {
|
|
return _firestore
|
|
.collection(alertsCollection)
|
|
.where('userId', isEqualTo: uid)
|
|
.orderBy('timestamp', descending: true)
|
|
.snapshots();
|
|
}
|
|
|
|
Future<void> markAlertAsRead(String alertId) async {
|
|
try {
|
|
await _firestore.collection(alertsCollection).doc(alertId).update({
|
|
'isRead': true,
|
|
});
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
print('Mark alert as read error: $e');
|
|
}
|
|
throw 'Gagal menandai alert sebagai dibaca';
|
|
}
|
|
}
|
|
|
|
// Device operations
|
|
Future<void> registerDevice({
|
|
required String uid,
|
|
required Map<String, dynamic> deviceData,
|
|
}) async {
|
|
try {
|
|
await _firestore.collection(devicesCollection).add({
|
|
'userId': uid,
|
|
'deviceName': deviceData['deviceName'] ?? '',
|
|
'deviceType': deviceData['deviceType'] ?? 'camera',
|
|
'location': deviceData['location'] ?? '',
|
|
'status': 'active',
|
|
'lastSeen': FieldValue.serverTimestamp(),
|
|
'createdAt': FieldValue.serverTimestamp(),
|
|
});
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
print('Register device error: $e');
|
|
}
|
|
throw 'Gagal mendaftarkan perangkat';
|
|
}
|
|
}
|
|
|
|
Stream<QuerySnapshot> getUserDevices(String uid) {
|
|
return _firestore
|
|
.collection(devicesCollection)
|
|
.where('userId', isEqualTo: uid)
|
|
.snapshots();
|
|
}
|
|
|
|
// Generic operations
|
|
Future<void> deleteDocument(String collection, String docId) async {
|
|
try {
|
|
await _firestore.collection(collection).doc(docId).delete();
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
print('Delete document error: $e');
|
|
}
|
|
throw 'Gagal menghapus dokumen';
|
|
}
|
|
}
|
|
|
|
Future<List<QueryDocumentSnapshot>> getDocuments({
|
|
required String collection,
|
|
Query? query,
|
|
}) async {
|
|
try {
|
|
QuerySnapshot snapshot =
|
|
query != null
|
|
? await query.get()
|
|
: await _firestore.collection(collection).get();
|
|
return snapshot.docs;
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
print('Get documents error: $e');
|
|
}
|
|
throw 'Gagal mengambil dokumen';
|
|
}
|
|
}
|
|
}
|