132 lines
4.4 KiB
Dart
132 lines
4.4 KiB
Dart
import 'package:cloud_firestore/cloud_firestore.dart';
|
|
import 'package:firebase_database/firebase_database.dart';
|
|
|
|
import '../models/sensor_data.dart';
|
|
|
|
class FirebaseService {
|
|
final DatabaseReference _database = FirebaseDatabase.instance.ref();
|
|
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
|
|
|
|
// === PENGAMBILAN PATH RTDB ===
|
|
Stream<SensorData> getSensorData() {
|
|
return _database.onValue.map((event) {
|
|
final data = event.snapshot.value as Map<dynamic, dynamic>;
|
|
return SensorData(
|
|
suhu: (data['suhu'] ?? 0.0).toDouble(),
|
|
timer: data['timer'] ?? 0,
|
|
manualMode: data['manualMode'] ?? false,
|
|
manualButton: data['manualButton'] ?? false,
|
|
elemen: data['elemen']?.toString() ?? 'off',
|
|
suhuMaks: data['suhuMaks'] ?? 45,
|
|
suhuMin: data['suhuMin'] ?? 40,
|
|
kadarAir: (data['kadarAir'] ?? 0.0).toDouble(),
|
|
);
|
|
});
|
|
}
|
|
|
|
// === UPDATEDATA RTDB ===
|
|
Future<void> updateManualMode(bool value) =>
|
|
_database.child('manualMode').set(value);
|
|
|
|
Future<void> updateManualButton(bool value) =>
|
|
_database.child('manualButton').set(value);
|
|
|
|
Future<void> updateElemen(String value) =>
|
|
_database.child('elemen').set(value);
|
|
|
|
Future<void> updateTimer(int value) => _database.child('timer').set(value);
|
|
|
|
Future<void> updateSuhuMaks(int value) =>
|
|
_database.child('suhuMaks').set(value);
|
|
|
|
Future<void> updateSuhuMin(int value) =>
|
|
_database.child('suhuMin').set(value);
|
|
|
|
Future<void> updateKadarAir(double value) =>
|
|
_database.child('kadarAir').set(value);
|
|
|
|
Future<void> updateKoneksiAndroid(bool value) =>
|
|
_database.child('koneksiandroid').set(value);
|
|
|
|
// Fungsi untuk mereset timer ke 0
|
|
Future<void> resetTimer() => _database.child('timer').set(0);
|
|
|
|
// === SYNC DATA RTDB TO FIRESTORE ===
|
|
|
|
/// Sinkron seluruh data dari RTDB path ke koleksi Firestore
|
|
Future<void> syncPathToFirestore(
|
|
String rtdbPath, String firestoreCollection) async {
|
|
try {
|
|
final snapshot = await _database.child(rtdbPath).get();
|
|
if (!snapshot.exists) return;
|
|
|
|
final data = snapshot.value as Map<dynamic, dynamic>;
|
|
final batch = _firestore.batch();
|
|
|
|
data.forEach((key, value) {
|
|
final docData = Map<String, dynamic>.from(value as Map)
|
|
..['timestamp'] = FieldValue.serverTimestamp();
|
|
final docRef =
|
|
_firestore.collection(firestoreCollection).doc(key.toString());
|
|
batch.set(docRef, docData);
|
|
});
|
|
|
|
await batch.commit();
|
|
print('Sync RTDB `$rtdbPath` → Firestore `$firestoreCollection` selesai');
|
|
} catch (e) {
|
|
print('Error syncPathToFirestore: $e');
|
|
}
|
|
}
|
|
|
|
/// Mirror perubahan RTDB secara realtime ke Firestore
|
|
void listenAndMirror(String rtdbPath, String firestoreCollection) {
|
|
final ref = _database.child(rtdbPath);
|
|
|
|
ref.onChildAdded.listen((event) {
|
|
final key = event.snapshot.key!;
|
|
final data = Map<String, dynamic>.from(event.snapshot.value as Map)
|
|
..['timestamp'] = FieldValue.serverTimestamp();
|
|
_firestore
|
|
.collection(firestoreCollection)
|
|
.doc(key)
|
|
.set(data)
|
|
.then((_) => verifyDocument(key))
|
|
.catchError((err) => print('onChildAdded error: $err'));
|
|
}, onError: (err) => print('RTDB onChildAdded listener error: $err'));
|
|
|
|
ref.onChildChanged.listen((event) {
|
|
final key = event.snapshot.key!;
|
|
final data = Map<String, dynamic>.from(event.snapshot.value as Map);
|
|
_firestore
|
|
.collection(firestoreCollection)
|
|
.doc(key)
|
|
.update(data)
|
|
.catchError((err) => print('onChildChanged error: $err'));
|
|
}, onError: (err) => print('RTDB onChildChanged listener error: $err'));
|
|
|
|
ref.onChildRemoved.listen((event) {
|
|
final key = event.snapshot.key!;
|
|
_firestore
|
|
.collection(firestoreCollection)
|
|
.doc(key)
|
|
.delete()
|
|
.catchError((err) => print('onChildRemoved error: $err'));
|
|
}, onError: (err) => print('RTDB onChildRemoved listener error: $err'));
|
|
}
|
|
|
|
/// Verifikasi bahwa dokumen tersimpan di Firestore
|
|
Future<void> verifyDocument(String docId) async {
|
|
try {
|
|
final doc =
|
|
await _firestore.collection('sensorData_firestore').doc(docId).get();
|
|
if (doc.exists) {
|
|
print('Verifikasi berhasil: ${doc.data()}');
|
|
} else {
|
|
print('Dokumen $docId tidak ditemukan di Firestore');
|
|
}
|
|
} catch (e) {
|
|
print('Verifikasi error: $e');
|
|
}
|
|
}
|
|
}
|