Cloud & IoT

Firebase Realtime Database untuk IoT: Panduan Lengkap ESP32

πŸ‘‘ Premium

Tutorial komprehensif Firebase Realtime Database untuk proyek IoT β€” dari membuat project hingga monitoring suhu dan kontrol relay via ESP32

1. Apa itu Firebase?

Firebase adalah platform pengembangan aplikasi Backend-as-a-Service (BaaS) yang dikembangkan oleh Google. Firebase menyediakan berbagai layanan siap pakai seperti database, autentikasi, hosting, cloud functions, dan banyak lagi β€” sehingga pengembang tidak perlu membangun backend dari nol.

Dalam konteks IoT, Firebase sangat populer karena menyediakan Realtime Database yang memungkinkan sinkronisasi data secara real-time antara perangkat (misalnya ESP32) dan cloud tanpa perlu menulis kode server yang rumit.

Realtime Database vs Cloud Firestore

Firebase menyediakan dua jenis layanan database utama:

Diagram: Perbandingan Realtime Database vs Firestore untuk IoT
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   Firebase Realtime Database                 β”‚
β”‚                                                              β”‚
β”‚   ESP32 ──→ Firebase ──→ Web Dashboard                      β”‚
β”‚   (Sensor)   (JSON Tree)   (Monitoring)                      β”‚
β”‚                                                              β”‚
β”‚   βœ… Sinkronisasi instan (milidetik)                        β”‚
β”‚   βœ… Simpel untuk data sensor time-series                   β”‚
β”‚   βœ… Library Arduino resmi tersedia                          β”‚
β”‚   ⚠️ Query terbatas (tidak ada range query kompleks)       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     Cloud Firestore                         β”‚
β”‚                                                              β”‚
β”‚   ESP32 ──→ Firestore ──→ Web Dashboard                    β”‚
β”‚   (Sensor)   (Dokumen)     (Monitoring)                     β”‚
β”‚                                                              β”‚
β”‚   βœ… Query lanjutan & indexing otomatis                     β”‚
β”‚   βœ… Scaling horizontal lebih baik                           β”‚
β”‚   ⚠️ Latensi lebih tinggi untuk real-time                   β”‚
β”‚   ⚠️ Library Arduino tidak resmi (community)               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
πŸ’‘ Tips untuk IoT

Untuk proyek IoT yang membutuhkan sinkronisasi data real-time dengan perangkat mikrokontroler, Realtime Database adalah pilihan yang lebih tepat. Firestore lebih cocok untuk aplikasi web atau mobile yang membutuhkan query data kompleks.

Fitur Firebase yang Relevan untuk IoT

Fitur Kegunaan untuk IoT
Realtime DatabaseMenyimpan dan menyinkronkan data sensor secara instan
Cloud FunctionsMenjalankan logika otomatis (trigger saat data berubah)
Firebase AuthAutentikasi perangkat IoT dengan token & API key
Security RulesKontrol akses baca/tulis per path database
HostingMenyimpan dashboard monitoring IoT
Cloud MessagingMengirim notifikasi ke aplikasi mobile saat data berubah
Billing (Free Tier)1 GB penyimpanan, 10 GB/bulan transfer data, 50K baca/hari

2. Setup Firebase Project

Sebelum menghubungkan ESP32 dengan Firebase, kamu perlu membuat project di Firebase Console dan mendapatkan kredensial yang diperlukan.

Langkah 1: Buat Project Firebase

  1. Buka browser dan kunjungi https://console.firebase.google.com/
  2. Login dengan akun Google kamu
  3. Klik tombol "Add project" (Proyek baru)
  4. Masukkan nama project, misalnya iot-monitoring-project
  5. Nonaktifkan opsi Google Analytics (opsional, tidak wajib untuk IoT)
  6. Klik "Create project" dan tunggu hingga selesai

Langkah 2: Aktifkan Realtime Database

  1. Di Firebase Console, pilih project yang baru dibuat
  2. Di menu sidebar kiri, klik "Realtime Database"
  3. Klik tombol "Create Database"
  4. Pilih lokasi server terdekat (misal: us-central1 atau asia-southeast1)
  5. Pilih mode "Start in test mode" (untuk pengembangan)
  6. Klik "Enable"

Langkah 3: Dapatkan API Key & Konfigurasi

  1. Di menu sidebar, klik ikon gear (βš™οΈ) β†’ "Project settings"
  2. Pilih tab "General"
  3. Scroll ke bagian "Your apps"
  4. Klik ikon "</>" (web app) β†’ register app web dengan nama
  5. Salin konfigurasi yang ditampilkan, terutama bagian:
Konfigurasi Firebase (Contoh)
const firebaseConfig = {
  apiKey: "AIzaSyBxxxxxxxxxxxxxxxxxxxxxxx",
  authDomain: "iot-monitoring-project.firebaseapp.com",
  databaseURL: "https://iot-monitoring-project-default-rtdb.firebaseio.com",
  projectId: "iot-monitoring-project",
  storageBucket: "iot-monitoring-project.appspot.com",
  messagingSenderId: "123456789012",
  appId: "1:123456789012:web:abcdef1234567890"
};
⚠️ Penting

Nilai databaseURL adalah yang paling penting untuk ESP32. URL ini memiliki format: https://<nama-project>-default-rtdb.firebaseio.com. Simpan URL ini baik-baik karena akan digunakan di kode Arduino.

Langkah 4: Aktifkan Anonymous Authentication

Untuk kemudahan pengujian, aktifkan autentikasi anonymous:

  1. Klik menu "Authentication" di sidebar
  2. Pilih tab "Sign-in method"
  3. Klik "Anonymous" β†’ Enable β†’ Save

3. Struktur Database Firebase untuk IoT

Desain struktur database yang baik sangat penting dalam proyek IoT. Firebase Realtime Database menggunakan struktur JSON tree, sehingga kita perlu merancangnya agar efisien untuk pembacaan dan penulisan data.

Prinsip Desain Database IoT

Diagram: Contoh Struktur Database Firebase untuk IoT
iot-monitoring-project-default-rtdb
β”‚
β”œβ”€β”€ devices/
β”‚   β”œβ”€β”€ esp32_001/
β”‚   β”‚   β”œβ”€β”€ info/
β”‚   β”‚   β”‚   β”œβ”€β”€ name: "Sensor Ruangan Tamu"
β”‚   β”‚   β”‚   β”œβ”€β”€ location: "Lantai 1"
β”‚   β”‚   β”‚   └── status: "online"
β”‚   β”‚   β”‚
β”‚   β”‚   β”œβ”€β”€ sensor/
β”‚   β”‚   β”‚   β”œβ”€β”€ temperature: 28.5
β”‚   β”‚   β”‚   β”œβ”€β”€ humidity: 65.2
β”‚   β”‚   β”‚   β”œβ”€β”€ timestamp: 1687238400000
β”‚   β”‚   β”‚   └── history/
β”‚   β”‚   β”‚       β”œβ”€β”€ 1687238400000: { temp: 28.5, hum: 65.2 }
β”‚   β”‚   β”‚       β”œβ”€β”€ 1687238460000: { temp: 28.7, hum: 65.0 }
β”‚   β”‚   β”‚       └── 1687238520000: { temp: 28.3, hum: 65.4 }
β”‚   β”‚   β”‚
β”‚   β”‚   └── control/
β”‚   β”‚       β”œβ”€β”€ relay1: false
β”‚   β”‚       β”œβ”€β”€ relay2: true
β”‚   β”‚       └── led: true
β”‚   β”‚
β”‚   └── esp32_002/
β”‚       └── ...
β”‚
β”œβ”€β”€ alerts/
β”‚   β”œβ”€β”€ 1687238400000:
β”‚   β”‚   β”œβ”€β”€ device: "esp32_001"
β”‚   β”‚   β”œβ”€β”€ type: "high_temp"
β”‚   β”‚   └── message: "Suhu melebihi 35Β°C"
β”‚   β”‚   └── read: false
β”‚   β”‚
└── settings/
    β”œβ”€β”€ auto_relay: true
    β”œβ”€β”€ temp_threshold_high: 35.0
    └── temp_threshold_low: 20.0
ℹ️ Kenapa Struktur Ini Efisien?

Dengan struktur di atas, ESP32 hanya perlu membaca path /devices/esp32_001/control untuk mengecek status relay tanpa harus mengunduh seluruh database. Ini sangat hemat bandwidth dan kuota Firebase gratis.

4. ESP32 + Firebase: Kirim Data Sensor

Sekarang saatnya menghubungkan ESP32 dengan Firebase! Kita akan menggunakan library Firebase ESP32 Client oleh mobizt yang merupakan library paling populer dan lengkap untuk Firebase IoT.

Instalasi Library Firebase

  1. Buka Arduino IDE
  2. Menu Tools β†’ Manage Libraries (atau Ctrl+Shift+I)
  3. Di kolom pencarian, ketik: Firebase ESP32 Client
  4. Install library "Firebase ESP32 Client" oleh mobizt (versi terbaru)

Wiring: ESP32 + DHT11

DHT11 Pin ESP32 Pin Keterangan
VCC (+)3.3VTegangan input
Data (Out)GPIO 4Pin data sensor
NCβ€”Tidak terpakai
GND (-)GNDGround

Jangan lupa pasang resistor pull-up 10kΞ© antara pin VCC dan Data pada DHT11.

Kode: Kirim Suhu & Kelembaban ke Firebase

C++ (Arduino)
/*
 * Kirim Data Sensor DHT11 ke Firebase Realtime Database
 * ESP32 + Firebase ESP32 Client Library
 * IoTHub - Tutorial Firebase IoT
 */

#include <WiFi.h>
#include <Firebase_ESP32.h>
#include <DHT.h>

// ===== KONFIGURASI WiFi =====
#define WIFI_SSID     "NamaWiFiKamu"
#define WIFI_PASSWORD "PasswordWiFiKamu"

// ===== KONFIGURASI Firebase =====
#define FIREBASE_HOST "iot-monitoring-project-default-rtdb.firebaseio.com"
#define FIREBASE_AUTH "AIzaSyBxxxxxxxxxxxxxxxxxxxxxxx"

// ===== KONFIGURASI SENSOR =====
#define DHT_PIN       4
#define DHT_TYPE      DHT11

// ===== INISIALISASI =====
DHT dht(DHT_PIN, DHT_TYPE);
FirebaseData firebaseData;
FirebaseConfig firebaseConfig;
FirebaseAuth firebaseAuth;

// Interval pengiriman data (dalam milidetik)
unsigned long previousMillis = 0;
const long interval = 10000; // Kirim data setiap 10 detik

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println("=== Firebase IoT: Kirim Data Sensor ===");

  // Inisialisasi sensor DHT
  dht.begin();
  Serial.println("Sensor DHT11 aktif");

  // Koneksi WiFi
  Serial.print("Menghubungkan WiFi");
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println();
  Serial.print("WiFi terhubung! IP: ");
  Serial.println(WiFi.localIP());

  // Konfigurasi Firebase
  firebaseConfig.database_url = FIREBASE_HOST;
  firebaseConfig.api_key = FIREBASE_AUTH;
  Firebase.begin(&firebaseConfig, &firebaseAuth);

  // Aktifkan auto-reconnect WiFi
  Firebase.reconnectWiFi(true);

  // Set ukuran buffer data rx/tx
  firebaseData.setResponseSize(1024);

  Serial.println("Firebase terhubung! Mulai mengirim data...");
}

void loop() {
  unsigned long currentMillis = millis();

  // Kirim data sesuai interval yang ditentukan
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    // Baca data dari sensor DHT11
    float suhu = dht.readTemperature();  // Celsius
    float kelembaban = dht.readHumidity();

    // Validasi pembacaan sensor
    if (isnan(suhu) || isnan(kelembaban)) {
      Serial.println("Gagal membaca sensor DHT11!");
      return;
    }

    // Tampilkan di Serial Monitor
    Serial.print("Suhu: ");
    Serial.print(suhu);
    Serial.print("Β°C | Kelembaban: ");
    Serial.print(kelembaban);
    Serial.println("%");

    // Kirim data suhu ke Firebase
    String path_suhu = "/devices/esp32_001/sensor/temperature";
    if (Firebase.setFloat(firebaseData, path_suhu, suhu)) {
      Serial.println("Suhu terkirim: " + String(suhu));
    } else {
      Serial.println("Gagal kirim suhu: " + firebaseData.errorReason());
    }

    // Kirim data kelembaban ke Firebase
    String path_hum = "/devices/esp32_001/sensor/humidity";
    if (Firebase.setFloat(firebaseData, path_hum, kelembaban)) {
      Serial.println("Kelembaban terkirim: " + String(kelembaban));
    } else {
      Serial.println("Gagal kirim kelembaban: " + firebaseData.errorReason());
    }

    // Kirim timestamp
    String path_time = "/devices/esp32_001/sensor/timestamp";
    if (Firebase.setInt(firebaseData, path_time, millis())) {
      Serial.println("Timestamp terkirim");
    }

    // Update status device
    String path_status = "/devices/esp32_001/info/status";
    Firebase.setString(firebaseData, path_status, "online");

    Serial.println("---");
  }
}
πŸ’‘ Tips Pengiriman Data

Hindari mengirim data terlalu sering ke Firebase (misal setiap 1 detik) karena bisa menghabiskan kuota free tier dengan cepat. Interval 10-30 detik sudah cukup untuk monitoring suhu pada umumnya.

5. ESP32 + Firebase: Baca Data Kontrol (LED ON/OFF)

Selain mengirim data sensor, ESP32 juga bisa membaca data dari Firebase untuk mengontrol perangkat. Misalnya, kita bisa mengontrol LED atau relay dari dashboard web melalui Firebase.

Konsep: Stream Listener untuk Kontrol Real-time

Firebase mendukung fitur streaming, yaitu ESP32 akan menerima pembaruan data secara otomatis setiap kali nilai di path tertentu berubah. Ini jauh lebih efisien daripada terus-menerus melakukan polling.

Diagram: Alur Kontrol LED via Firebase
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     Ubah nilai      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     Stream/Listener    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Browser β”‚  ──────────────────→ β”‚   Firebase   β”‚ ─────────────────────→ β”‚   ESP32  β”‚
β”‚Dashboard β”‚   relay1 = true      β”‚  Realtime DB β”‚   Path berubah!       β”‚ LED ON βœ“ β”‚
β”‚          β”‚                      β”‚              β”‚                       β”‚          β”‚
β”‚          β”‚  ←────────────────── β”‚              β”‚ ←──────────────────── β”‚          β”‚
β”‚          β”‚   Status terupdate   β”‚              β”‚   Kirim status baru   β”‚          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Kode: Kontrol LED & Relay via Firebase Stream

C++ (Arduino)
/*
 * Kontrol LED & Relay via Firebase Realtime Database
 * ESP32 - Stream Listener untuk perubahan data real-time
 * IoTHub - Tutorial Firebase IoT
 */

#include <WiFi.h>
#include <Firebase_ESP32.h>

// ===== KONFIGURASI WiFi =====
#define WIFI_SSID     "NamaWiFiKamu"
#define WIFI_PASSWORD "PasswordWiFiKamu"

// ===== KONFIGURASI Firebase =====
#define FIREBASE_HOST "iot-monitoring-project-default-rtdb.firebaseio.com"
#define FIREBASE_AUTH "AIzaSyBxxxxxxxxxxxxxxxxxxxxxxx"

// ===== PIN OUTPUT =====
#define LED_PIN       2    // LED bawaan ESP32
#define RELAY1_PIN    16   // Relay module channel 1
#define RELAY2_PIN    17   // Relay module channel 2

// ===== INISIALISASI =====
FirebaseData firebaseData;
FirebaseConfig firebaseConfig;
FirebaseAuth firebaseAuth;

// Path path di Firebase
const char* pathControl = "/devices/esp32_001/control";

void streamCallback(StreamData data) {
  // Dipanggil setiap kali data berubah di path yang di-listen
  Serial.println("=== DATA BERUBAH ===");
  Serial.print("Path: ");
  Serial.println(data.dataPath());
  Serial.print("Tipe data: ");
  Serial.println(data.dataType());
  Serial.print("Nilai baru: ");
  Serial.println(data.stringData());

  // Cek path yang berubah dan jalankan aksi
  String path = data.dataPath();
  String value = data.stringData();

  if (path == "/led") {
    // Kontrol LED bawaan ESP32
    if (value == "true") {
      digitalWrite(LED_PIN, HIGH);
      Serial.println("LED ON");
    } else {
      digitalWrite(LED_PIN, LOW);
      Serial.println("LED OFF");
    }
  }
  else if (path == "/relay1") {
    // Kontrol Relay Channel 1
    if (value == "true") {
      digitalWrite(RELAY1_PIN, HIGH);
      Serial.println("Relay 1 ON");
    } else {
      digitalWrite(RELAY1_PIN, LOW);
      Serial.println("Relay 1 OFF");
    }
  }
  else if (path == "/relay2") {
    // Kontrol Relay Channel 2
    if (value == "true") {
      digitalWrite(RELAY2_PIN, HIGH);
      Serial.println("Relay 2 ON");
    } else {
      digitalWrite(RELAY2_PIN, LOW);
      Serial.println("Relay 2 OFF");
    }
  }
}

void streamTimeoutCallback(bool timeout) {
  if (timeout) {
    Stream timeoutStream;
    Serial.println("Stream timeout, reconnect...");
    // Mulai ulang stream listener
    if (!Firebase.readStream(firebaseData)) {
      Serial.println("Gagal mulai ulang stream: " + firebaseData.errorReason());
    }
  }
}

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println("=== Firebase IoT: Kontrol LED & Relay ===");

  // Setup pin output
  pinMode(LED_PIN, OUTPUT);
  pinMode(RELAY1_PIN, OUTPUT);
  pinMode(RELAY2_PIN, OUTPUT);

  // Pastikan semua relay OFF saat awal
  digitalWrite(LED_PIN, LOW);
  digitalWrite(RELAY1_PIN, LOW);
  digitalWrite(RELAY2_PIN, LOW);

  // Koneksi WiFi
  Serial.print("Menghubungkan WiFi");
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println();
  Serial.print("WiFi terhubung! IP: ");
  Serial.println(WiFi.localIP());

  // Konfigurasi Firebase
  firebaseConfig.database_url = FIREBASE_HOST;
  firebaseConfig.api_key = FIREBASE_AUTH;
  Firebase.begin(&firebaseConfig, &firebaseAuth);
  Firebase.reconnectWiFi(true);

  // Inisialisasi nilai awal di Firebase (jika belum ada)
  if (!Firebase.pathExist(firebaseData, "/devices/esp32_001/control")) {
    Serial.println("Membuat node kontrol awal...");
    FirebaseJson json;
    json.set("led", false);
    json.set("relay1", false);
    json.set("relay2", false);
    Firebase.set(firebaseData, "/devices/esp32_001/control", json);
  }

  // Mulai stream listener untuk path kontrol
  if (!Firebase.beginStream(firebaseData, pathControl)) {
    Serial.println("Gagal mulai stream: " + firebaseData.errorReason());
    return;
  }

  // Set callback untuk perubahan data
  Firebase.setStreamCallback(firebaseData, streamCallback, streamTimeoutCallback);

  Serial.println("Stream listener aktif! Menunggu perubahan data...");
}

void loop() {
  // Pastikan koneksi WiFi tetap aktif
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("WiFi terputus! Menghubungkan ulang...");
    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
    }
    Serial.println("WiFi terhubung kembali!");
  }

  // Stream listener bekerja di background, tidak perlu polling
  delay(1000);
}
⚠️ Catatan Penting tentang Stream

Gunakan path spesifik saat menggunakan beginStream(). Jangan gunakan path root (/) karena Firebase akan mengalirkan seluruh data database yang akan membebani ESP32.

6. Firebase Security Rules untuk IoT

Security Rules adalah komponen krusial yang sering diabaikan dalam proyek IoT. Tanpa rules yang tepat, siapa pun bisa membaca data sensor atau mengontrol perangkat kamu dari internet!

Mengapa Security Rules Penting untuk IoT?

Contoh Security Rules untuk IoT

Firebase Security Rules (JSON)
{
  "rules": {
    "devices": {
      // Setiap device hanya bisa diakses dengan device ID yang benar
      "$device_id": {
        // Info device: baca semua, tulis hanya owner
        "info": {
          ".read": "auth != null",
          ".write": "auth != null && root.child('users').child(auth.uid).child('devices').child($device_id).exists()"
        },
        // Data sensor: baca semua yang terautentikasi, tulis hanya device sendiri
        "sensor": {
          ".read": "auth != null",
          ".write": "auth != null && root.child('devices').child($device_id).child('info/api_key').val() === data.parent().child('info/api_key').val()"
        },
        // Data kontrol: baca semua, tulis semua (untuk dashboard web)
        "control": {
          ".read": "auth != null",
          ".write": "auth != null"
        }
      }
    },
    // Pengaturan threshold: baca semua, tulis hanya admin
    "settings": {
      ".read": "auth != null",
      ".write": "auth != null && root.child('users').child(auth.uid).child('role').val() === 'admin'"
    },
    // Log aksi: baca semua, tulis hanya device
    "logs": {
      ".read": "auth != null",
      ".write": false,
      "$log_id": {
        ".validate": "newData.hasChildren(['timestamp', 'device', 'action'])"
      }
    },
    // Aturan default: tolak semua yang tidak didefinisikan
    "$other": {
      ".read": false,
      ".write": false
    }
  }
}

Menjalankan Security Rules

  1. Di Firebase Console, buka Realtime Database
  2. Klik tab "Rules"
  3. Tempelkan JSON rules di atas (sesuaikan dengan kebutuhanmu)
  4. Klik "Publish"
⚠️ Peringatan Test Mode

Mode "test mode" memungkinkan siapa pun membaca dan menulis data tanpa autentikasi. Mode ini hanya untuk pengembangan awal. SELALU update ke production rules sebelum menggunakan di proyek nyata!

7. Firebase vs MQTT vs HTTP: Perbandingan

Ada beberapa protokol komunikasi yang bisa digunakan untuk IoT cloud. Berikut perbandingan lengkap Firebase Realtime Database, MQTT, dan HTTP REST API.

Diagram: Arsitektur Komunikasi Tiga Protokol IoT
         Firebase Realtime DB           MQTT Broker              HTTP REST API
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚                    β”‚      β”‚                  β”‚      β”‚                  β”‚
        β”‚  ESP32 ──HTTPS──→  β”‚      β”‚  ESP32 ──TCP──→  β”‚      β”‚  ESP32 ──HTTPS──→ β”‚
        β”‚  Firebase Server   β”‚      β”‚  MQTT Broker     β”‚      β”‚  REST API Server β”‚
        β”‚        ↓           β”‚      β”‚        ↓         β”‚      β”‚        ↓         β”‚
        β”‚  Real-time sync    β”‚      β”‚  Pub/Sub message β”‚      β”‚  Request/Responseβ”‚
        β”‚  via WebSocket     β”‚      β”‚  via Topics      β”‚      β”‚                  β”‚
        β”‚                    β”‚      β”‚                  β”‚      β”‚                  β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             Alat: Web Dashboard         Alat: Node-RED              Alat: Grafana
                  Firebase Console           Grafana                   Grafana
Aspek Firebase RTDB MQTT HTTP REST
Protokol dasar WebSocket / HTTPS TCP (port 1883/8883) HTTP/HTTPS
Kontrol Real-time βœ… Otomatis (stream) βœ… Pub/Sub instant ❌ Harus polling
Bandwidth Sedang (JSON) 🟒 Sangat rendah (binary) πŸ”΄ Tinggi (HTTP headers)
Daya baterai Sedang 🟒 Sangat hemat πŸ”΄ Boros
Mudah untuk pemula 🟒 Sangat mudah Mudah Mudah
Dashboard built-in βœ… Firebase Console ❌ Perlu tool tambahan ❌ Perlu buat sendiri
Autentikasi βœ… Built-in (token/API key) Username/password TLS Token/JWT manual
Query data ⚠️ Terbatas ❌ Tidak ada (hanya topic) βœ… Lengkap (GET param)
Free tier 1 GB storage, 10 GB/mo Broker publik gratis Tergantung provider
Skalabilitas Google infrastructure Self-hosted atau cloud Tergantung arsitektur
Kapan pakai? Dashboard monitoring, CRUD mudah Banyak device, hemat daya Integrasi dengan API eksternal
ℹ️ Kapan Pilih Firebase?

Firebase adalah pilihan terbaik ketika kamu membutuhkan dashboard monitoring real-time yang cepat dibangun, kombinasi kirim + kontrol data dalam satu platform, dan tidak ingin mengelola broker/server sendiri. Untuk skala ribuan device, pertimbangkan MQTT atau kombinasi keduanya.

8. Proyek: Sistem Monitoring Suhu + Kontrol Relay via Firebase

Mari kita satukan semua yang sudah dipelajari ke dalam satu proyek lengkap! Proyek ini menggabungkan pengiriman data sensor (suhu + kelembaban) dan kontrol relay (untuk menghidupkan/mematikan perangkat) melalui Firebase Realtime Database.

Komponen yang Dibutuhkan

Komponen Jumlah Fungsi
ESP32 DevKit v11Mikrokontroler utama
Sensor DHT11/DHT221Mengukur suhu dan kelembaban
Relay Module 2 Channel 5V1Mengontrol perangkat AC (lampu, kipas)
LED merah + hijau2Indikator status sistem
Resistor 220Ξ©2Pembatas arus untuk LED
Resistor 10kΞ©1Pull-up untuk DHT11
Breadboard + jumper wireβ€”Prototyping

Diagram Wiring

Diagram: Koneksi ESP32 + DHT11 + Relay + LED
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚           ESP32 DevKit v1        β”‚
                    β”‚                                  β”‚
    DHT11 ────────── GPIO 4  (D4)                    β”‚
                    β”‚                                  β”‚
    LED Hijau ────── GPIO 2  (D2)  ← LED Bawaan     β”‚
    LED Merah ────── GPIO 15 (D15)                    β”‚
                    β”‚                                  β”‚
    Relay CH1 ────── GPIO 16 (D16) ← Kipas Angin     β”‚
    Relay CH2 ────── GPIO 17 (D17) ← Lampu           β”‚
                    β”‚                                  β”‚
    Relay COM ────── 5V                               β”‚
    DHT11 VCC ────── 3.3V                             β”‚
                    β”‚                                  β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

    DHT11 Pinout:
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”
    β”‚ DHT11 β”‚     VCC ──→ 3.3V (ESP32)
    β”‚       β”‚     DATA ──→ GPIO 4 + Resistor 10kΞ© ke 3.3V
    β”‚ 1 2 3 β”‚     NC
    β”‚       β”‚     GND ──→ GND (ESP32)
    β””β”€β”€β”€β”€β”€β”€β”€β”˜

Kode Lengkap: Proyek Monitoring + Kontrol

C++ (Arduino) β€” Proyek Lengkap
/*
 * Proyek Lengkap: Monitoring Suhu + Kontrol Relay via Firebase
 * ESP32 + DHT11 + Relay 2 Channel
 * IoTHub - Tutorial Firebase IoT
 *
 * Fitur:
 *   1. Mengirim data suhu & kelembaban ke Firebase setiap 15 detik
 *   2. Monitoring status LED (online/offline) di Firebase
 *   3. Kontrol relay real-time via Firebase stream listener
 *   4. Alert otomatis jika suhu melebihi threshold
 */

#include <WiFi.h>
#include <Firebase_ESP32.h>
#include <DHT.h>
#include <time.h>

// ===== KONFIGURASI WiFi =====
#define WIFI_SSID     "NamaWiFiKamu"
#define WIFI_PASSWORD "PasswordWiFiKamu"

// ===== KONFIGURASI Firebase =====
#define FIREBASE_HOST "iot-monitoring-project-default-rtdb.firebaseio.com"
#define FIREBASE_AUTH "AIzaSyBxxxxxxxxxxxxxxxxxxxxxxx"

// ===== PIN KONFIGURASI =====
#define DHT_PIN       4
#define DHT_TYPE      DHT11
#define LED_GREEN     2    // LED indikator online
#define LED_RED       15   // LED indikator error
#define RELAY1_PIN    16   // Relay CH1 - Kipas Angin
#define RELAY2_PIN    17   // Relay CH2 - Lampu

// ===== THRESHOLD =====
#define TEMP_HIGH     35.0 // Suhu tinggi (Β°C) - trigger alert
#define TEMP_LOW      18.0 // Suhu rendah (Β°C) - trigger alert

// ===== INISIALISASI =====
DHT dht(DHT_PIN, DHT_TYPE);
FirebaseData firebaseData;
FirebaseData streamData;
FirebaseConfig firebaseConfig;
FirebaseAuth firebaseAuth;

// Device ID unik
const String DEVICE_ID = "esp32_001";

// Timing
unsigned long prevSendTime = 0;
const long sendInterval = 15000; // 15 detik

// ===== FUNGSI CALLBACK STREAM =====
void onControlChange(StreamData data) {
  String path = data.dataPath();
  String value = data.stringData();

  Serial.printf("[KONTROL] %s = %s\n", path.c_str(), value.c_str());

  if (path == "/relay1") {
    bool state = (value == "true");
    digitalWrite(RELAY1_PIN, state ? HIGH : LOW);
    Serial.printf("  β†’ Relay 1 (Kipas): %s\n", state ? "ON" : "OFF");
  }
  else if (path == "/relay2") {
    bool state = (value == "true");
    digitalWrite(RELAY2_PIN, state ? HIGH : LOW);
    Serial.printf("  β†’ Relay 2 (Lampu): %s\n", state ? "ON" : "OFF");
  }
}

void onStreamTimeout(bool timeout) {
  if (timeout) {
    Serial.println("[STREAM] Timeout! Reconnecting...");
    Firebase.readStream(streamData);
  }
}

// ===== FUNGSI KIRIM ALERT =====
void sendAlert(String type, String message) {
  String path = "/alerts/" + String(millis());
  FirebaseJson alertJson;
  alertJson.set("device", DEVICE_ID);
  alertJson.set("type", type);
  alertJson.set("message", message);
  alertJson.set("timestamp", millis());
  alertJson.set("read", false);

  if (Firebase.setJSON(streamData, path, alertJson)) {
    Serial.println("[ALERT] Terkirim: " + message);
  }
}

// ===== FUNGSI KIRIM DATA SENSOR =====
void sendSensorData(float suhu, float kelembaban) {
  String basePath = "/devices/" + DEVICE_ID + "/sensor/";

  // Kirim data terkini
  Firebase.setFloat(streamData, basePath + "temperature", suhu);
  Firebase.setFloat(streamData, basePath + "humidity", kelembaban);
  Firebase.setInt(streamData, basePath + "timestamp", millis());

  // Simpan history (opsional, untuk grafik)
  String historyPath = basePath + "history/" + String(millis()) + "/";
  FirebaseJson histJson;
  histJson.set("temp", suhu);
  histJson.set("hum", kelembaban);
  Firebase.setJSON(streamData, historyPath, histJson);

  // Cek threshold dan kirim alert
  if (suhu > TEMP_HIGH) {
    sendAlert("high_temp", "Suhu " + String(suhu) + "Β°C melebihi batas " + String(TEMP_HIGH) + "Β°C");
  }
  else if (suhu < TEMP_LOW) {
    sendAlert("low_temp", "Suhu " + String(suhu) + "Β°C di bawah batas " + String(TEMP_LOW) + "Β°C");
  }
}

// ===== SETUP =====
void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println("========================================");
  Serial.println("  Firebase IoT - Monitoring + Kontrol");
  Serial.println("  IoTHub Tutorial");
  Serial.println("========================================");

  // Setup pin
  pinMode(LED_GREEN, OUTPUT);
  pinMode(LED_RED, OUTPUT);
  pinMode(RELAY1_PIN, OUTPUT);
  pinMode(RELAY2_PIN, OUTPUT);

  // Default: semua OFF
  digitalWrite(LED_GREEN, LOW);
  digitalWrite(LED_RED, LOW);
  digitalWrite(RELAY1_PIN, LOW);
  digitalWrite(RELAY2_PIN, LOW);

  // Mulai sensor
  dht.begin();
  Serial.println("[INIT] Sensor DHT11 aktif");

  // Koneksi WiFi
  Serial.print("[WIFI] Menghubungkan");
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  int retries = 0;
  while (WiFi.status() != WL_CONNECTED && retries < 30) {
    Serial.print(".");
    delay(500);
    retries++;
  }

  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("\n[FATAL] WiFi gagal! Restart...");
    ESP.restart();
  }

  Serial.println();
  Serial.printf("[WIFI] Terhubung! IP: %s\n", WiFi.localIP().toString().c_str());
  digitalWrite(LED_GREEN, HIGH); // LED hijau ON = WiFi OK

  // Setup NTP time
  configTime(0, 0, "pool.ntp.org", "time.nist.gov");

  // Konfigurasi Firebase
  firebaseConfig.database_url = FIREBASE_HOST;
  firebaseConfig.api_key = FIREBASE_AUTH;
  Firebase.begin(&firebaseConfig, &firebaseAuth);
  Firebase.reconnectWiFi(true);
  streamData.setResponseSize(4096);

  // Update status online
  String infoPath = "/devices/" + DEVICE_ID + "/info/";
  FirebaseJson infoJson;
  infoJson.set("name", "Monitoring Ruangan");
  infoJson.set("location", "Lantai 1");
  infoJson.set("status", "online");
  infoJson.set("ip", WiFi.localIP().toString());
  Firebase.setJSON(streamData, infoPath, infoJson);

  // Inisialisasi node kontrol jika belum ada
  if (!Firebase.pathExist(streamData, "/devices/" + DEVICE_ID + "/control")) {
    FirebaseJson ctrlJson;
    ctrlJson.set("relay1", false);
    ctrlJson.set("relay2", false);
    Firebase.setJSON(streamData, "/devices/" + DEVICE_ID + "/control", ctrlJson);
  }

  // Mulai stream listener untuk kontrol
  String controlPath = "/devices/" + DEVICE_ID + "/control";
  if (!Firebase.beginStream(streamData, controlPath)) {
    Serial.println("[STREAM] Gagal mulai: " + streamData.errorReason());
  } else {
    Firebase.setStreamCallback(streamData, onControlChange, onStreamTimeout);
    Serial.println("[STREAM] Listener kontrol aktif");
  }

  Serial.println("[SYSTEM] Siap! Memulai siklus monitoring...");
  Serial.println("========================================");
}

// ===== LOOP =====
void loop() {
  unsigned long now = millis();

  // Cek WiFi
  if (WiFi.status() != WL_CONNECTED) {
    digitalWrite(LED_GREEN, LOW);
    digitalWrite(LED_RED, HIGH);
    Serial.println("[WIFI] Terputus! Menghubungkan ulang...");
    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
    delay(5000);
    return;
  }

  digitalWrite(LED_GREEN, HIGH);
  digitalWrite(LED_RED, LOW);

  // Kirim data sensor sesuai interval
  if (now - prevSendTime >= sendInterval) {
    prevSendTime = now;

    float suhu = dht.readTemperature();
    float kelembaban = dht.readHumidity();

    if (isnan(suhu) || isnan(kelembaban)) {
      Serial.println("[SENSOR] Gagal baca DHT11!");
      Firebase.setString(streamData, "/devices/" + DEVICE_ID + "/info/status", "sensor_error");
      return;
    }

    // Kirim ke Firebase
    sendSensorData(suhu, kelembaban);

    // Cek status relay dari Firebase
    FirebaseJson relayStatus;
    String relayPath = "/devices/" + DEVICE_ID + "/control";
    if (Firebase.getJSON(streamData, relayPath)) {
      FirebaseJson &json = streamData.jsonObject();
      FirebaseJsonData jsonData;

      if (json.get(jsonData, "relay1")) {
        Serial.printf("  Relay1: %s\n", jsonData.stringValue);
      }
      if (json.get(jsonData, "relay2")) {
        Serial.printf("  Relay2: %s\n", jsonData.stringValue);
      }
    }

    Serial.printf("[DATA] Suhu: %.1fΒ°C | Kelembaban: %.1f%%\n", suhu, kelembaban);
    Serial.println("---");
  }

  delay(100);
}
πŸ’‘ Ekspansi Proyek

Proyek ini bisa dikembangkan lebih lanjut dengan menambahkan: (1) Dashboard web menggunakan Chart.js untuk grafik data sensor, (2) Notifikasi push ke smartphone via Firebase Cloud Messaging, (3) Logika otomatis menggunakan Firebase Cloud Functions, atau (4) Multiple ESP32 yang terhubung ke project yang sama.

9. Quiz: Uji Pemahamanmu!

Setelah membaca tutorial di atas, jawablah 5 pertanyaan berikut untuk menguji pemahamanmu tentang Firebase untuk IoT:

Pertanyaan 1: Layanan Firebase mana yang paling cocok untuk sinkronisasi data real-time dengan mikrokontroler seperti ESP32?

a) Realtime Database
b) Cloud Firestore
c) Firebase Hosting
d) Cloud Functions

Pertanyaan 2: Fungsi dari Firebase.beginStream() dalam kode ESP32 adalah...

a) Mengirim data sensor ke Firebase
b) Menghapus data dari Firebase
c) Membuka listener yang memantau perubahan data secara real-time
d) Membuat project Firebase baru

Pertanyaan 3: Mengapa disarankan untuk tidak mengirim data sensor ke Firebase setiap 1 detik?

a) Karena Firebase tidak mendukung data cepat
b) Karena akan menghabiskan kuota free tier dengan cepat
c) Karena ESP32 akan overheating
d) Karena Firebase akan memblokir device

Pertanyaan 4: Pernyataan berikut yang BENAR tentang keamanan Firebase untuk IoT adalah...

a) Security Rules hanya berlaku untuk Firestore
b) Mode test mode aman digunakan di production
c) Security Rules Realtime Database menggunakan format JSON
d) Security Rules tidak bisa membatasi akses per path

Pertanyaan 5: Protokol mana yang paling hemat bandwidth untuk komunikasi IoT?

a) HTTP REST API
b) Firebase Realtime Database
c) WebSocket tanpa kompresi
d) MQTT dengan binary payload
← Sebelumnya Raspberry Pi untuk IoT Selanjutnya β†’ MikroTik Firewall