week__11 (Firebase) - JINEEH/SmartDevice_JinHee GitHub Wiki

Firebase & ๋น› ์„ผ์„œ ์‹ค์Šต

1. ํ•™์Šต ๋ชฉํ‘œ

1-1. Firebase๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์ €์žฅ ๋ฐ ํ™œ์šฉ

2. Firebase

2-1. ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋น ๋ฅด๊ณ  ์‰ฝ๊ฒŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋ฉฐ ๋‹ค์–‘ํ•œ ๊ธฐ๋Š˜์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Œ
     - ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๋ฌด๋ฃŒ๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
     - ๋ฐ์ดํ„ฐ ๋ณด์•ˆ๊ณผ ๊ด€๋ จ๋œ ์ธ์ฆ๊ธฐ๋Šฅ(ex: ์ด๋ฉ”์ผ, SNS ๋กœ๊ทธ์ธ)๊ณผ ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํด๋ผ์šฐ๋“œ ๋ฐฉ์‹ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
     - ์‚ฌ์šฉ์ž or ๋””๋ฐ”์ด์Šค์—์„œ ์ž…๋ ฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต์œ (ํŒŒ์ผ ์—…๋กœ๋“œ ๊ณต์œ  ๊ธฐ๋Šฅ) ๊ฐ€๋Šฅ
     - ๋ฐ์ดํ„ฐ ์ž๋™ ๋ถ„์„ ๊ธฐ๋Šฅ
     - ๋ฉ”์‹œ์ง• ๊ธฐ๋Šฅ๊ณผ ๋ฐฑ์—…๊ณผ ๊ด€๋ จ๋œ ์Šคํ† ๋ฆฌ์ง€ ๊ธฐ๋Šฅ
     - ๋ฐ์ดํ„ฐ ์ €์žฅ/๊ณต์œ /๋ถ„์„/๋ณด์•ˆ/๋ฐฑ์—…

2-2. Firebase ์„ค์น˜ ๋ฐฉ๋ฒ•

  • ๊ตฌ๊ธ€ ์•„์ด๋””๋กœ ๋กœ๊ทธ์ธ ํ›„ ํ”„๋กœ์ ํŠธ ๋งŒ๋“ค๊ธฐ ์‹คํ–‰ 11์ฃผ์ฐจ Firebase-1

  • ํ”„๋กœ์ ํŠธ ์ด๋ฆ„ ์ž…๋ ฅ ํ›„ ๋นŒ๋“œ->Realtime Database->๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋งŒ๋“ค๊ธฐ

  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„œ๋ฒ„์˜ ์œ„์น˜(๋ฏธ๊ตญ) ๋ฐ ํ…Œ์ŠคํŠธ ๋ชจ๋“œ ์„ค์ • ํ›„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค URL ๋ณต์‚ฌ ๋ฐ ์ฝ๊ธฐ, ์“ฐ๊ธฐ ๊ทœ์น™ ์„ค์ •

11์ฃผ์ฐจ Firebase-6 11์ฃผ์ฐจ Firebase-7

  • ๋นŒ๋“œ->AUthentication ์ด๋™ ํ›„ ์‹œ์ž‘ํ•˜๊ธฐ

11์ฃผ์ฐจ Firebase-8

  • ์ต๋ช… ๋ฐฉ์‹ ์„ ํƒ ํ›„ ์‚ฌ์šฉ ์„ค์ • On

11์ฃผ์ฐจ Firebase-9

  • <ํ”„๋กœ์ ํŠธ ์„ค์ •>์—์„œ ์›น API ํ‚ค ํ™•์ธ ๋ฐ ๋ณต์‚ฌ

11์ฃผ์ฐจ Firebase-10

3. Firebase๋ฅผ ํ™œ์šฉํ•œ ESP32 ๋‚ด์žฅ LED ์‹ค์Šต

  • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜

11์ฃผ์ฐจ 7-1(1)

  • ์‹คํ–‰ ์ฝ”๋“œ
#include <WiFi.h>
#include <FirebaseESP32.h>

//Provide the token generation process info.
#include "addons/TokenHelper.h"
//Provide the RTDB payload printing info and other helper functions.
#include "addons/RTDBHelper.h"

// Firebase ์„ค์ •
#define FIREBASE_HOST "your_firebase_host"
#define FIREBASE_AUTH "your_firebase_auth"
#define WIFI_SSID "your_wifi_ssid"
#define WIFI_PASSWORD "your_wifi_password"

// ๋‚ด์žฅ LED ํ•€ ์„ค์ •
#define LED_PIN 2

// Firebase ๊ฐ์ฒด ์ƒ์„ฑ
FirebaseData firebaseData;

FirebaseAuth auth;
FirebaseConfig config;
bool signupOK = false;
unsigned long sendDataPrevMillis = 0;

void setup_wifi() {
  delay(10);
  // Wi-Fi ๋„คํŠธ์›Œํฌ์— ์—ฐ๊ฒฐ ์‹œ์ž‘
  Serial.println();
  Serial.print("์—ฐ๊ฒฐ ์ค‘์ธ Wi-Fi: ");
  Serial.println(WIFI_SSID);

  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("Wi-Fi ์—ฐ๊ฒฐ๋จ");
  Serial.println("IP ์ฃผ์†Œ: ");
  Serial.println(WiFi.localIP());
}

void setup() {
  // ์‹œ๋ฆฌ์–ผ ํ†ต์‹  ์ดˆ๊ธฐํ™”
  Serial.begin(115200);

  // WiFi ์—ฐ๊ฒฐ
  setup_wifi();

  // API ํ‚ค๋ฅผ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค.(ํ•„์ˆ˜)
  config.api_key = FIREBASE_AUTH;

  //RTDB URL์„ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค.(ํ•„์ˆ˜)
  config.database_url = FIREBASE_HOST;

  /* Sign up */
  if (Firebase.signUp(&config, &auth, "", "")){
    Serial.println("ok");
    signupOK = true;
  }
  else{
    Serial.printf("%s\n", config.signer.signupError.message.c_str());
  }

  // ๊ธด ์‹คํ–‰ ์‹œ๊ฐ„์ด ํ•„์š”ํ•œ ํ† ํฐ ์ƒ์„ฑ ์ž‘์—…์„ ์œ„ํ•œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค.
  config.token_status_callback = tokenStatusCallback; 

  Firebase.begin(&config, &auth);
  Firebase.reconnectWiFi(true);
  // ๋‚ด์žฅ LED ํ•€ ์„ค์ •
  pinMode(LED_PIN, OUTPUT);

  // "/ledState" ๊ฒฝ๋กœ๋ฅผ 0์œผ๋กœ ์ดˆ๊ธฐํ™”
  if (Firebase.ready() && signupOK)
  {
    if (Firebase.RTDB.setInt(&firebaseData, "/ledState", 0)){
      Serial.println("PASSED");
      Serial.println("PATH: " + firebaseData.dataPath());
      Serial.println("TYPE: " + firebaseData.dataType());
    }
    else {
      Serial.println("FAILED");
      Serial.println("REASON: " + firebaseData.errorReason());
    }
  }
}
void loop() {
  // Firebase.ready() ํ•จ์ˆ˜๋Š” ์ธ์ฆ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ˜๋ณต์ ์œผ๋กœ ํ˜ธ์ถœ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  if (Firebase.ready() && signupOK && \
  (millis() - sendDataPrevMillis > 2000 || sendDataPrevMillis == 0))
  {
    sendDataPrevMillis = millis();

    // Firebase์—์„œ LED ์ƒํƒœ ๊ฐ€์ ธ์˜ค๊ธฐ
    int ledState = 0;
    if (Firebase.RTDB.getInt(&firebaseData, "/ledState")) {
      if (firebaseData.dataType() == "int") {
        ledState = firebaseData.intData();
        Serial.println(ledState);
        if (ledState == 1) {
          digitalWrite(LED_PIN, HIGH);
        } else {
          digitalWrite(LED_PIN, LOW);
        }
      }
    }
    else {
        Serial.println(firebaseData.errorReason());
    }
  }
}
  • ์‹ค์Šต ๊ฒฐ๊ณผ
11.7-1.2.mp4

4-1. Firebase๋ฅผ ํ™œ์šฉํ•œ ๋น› ๊ฐ์ง€ ์„ผ์„œ๊ฐ’ ์ฝ๊ธฐ

  • ์ค€๋น„๋ฌผ: ESP32, ESP32 ํ™•์žฅ ์‹ค๋“œ, ์ดˆ์ŒํŒŒ ์„ผ์„œ, ์ ํผ์ผ€์ด๋ธ” 3๊ฐœ
  • ์‹คํ–‰ ์ฝ”๋“œ
int sensorPin = 34;
int value = 0;

void setup() {
  Serial.begin(115200);
}

void loop() {
  value = analogRead(sensorPin);

  Serial.println(value);

  delay(500);
}
  • ์‹ค์Šต ๊ฒฐ๊ณผ
  • 4์ดˆ์— ๋น› ์ฆ๊ฐ€, 14์ดˆ์— ๋น› ๊ฐ์†Œ๋กœ ์ธํ•œ ๋ณ€ํ™” ํ™•์ธ
11.7-2.mp4

4-2. Firebase๋ฅผ ํ™œ์šฉํ•œ ๋น› ๊ฐ์ง€ ์„ผ์„œ๊ฐ’ ๋ฐ์ดํ„ฐ ๋กœ๊น…

  • ESP32์˜ ํƒ€์ž„์Šคํƒฌํ”„๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Firebase ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ฐ์ดํ„ฐ ๋กœ๊น…ํ•˜๊ธฐ
  • ์‹คํ–‰ ์ฝ”๋“œ
#include <WiFi.h>
#include <FirebaseESP32.h>

// ํ† ํฐ ์ƒ์„ฑ ํ”„๋กœ์„ธ์Šค ์ •๋ณด ์ œ๊ณต
#include "addons/TokenHelper.h"
// RTDB ํŽ˜์ด๋กœ๋“œ ์ถœ๋ ฅ ์ •๋ณด ๋ฐ ๊ธฐํƒ€ ๋„์›€ ํ•จ์ˆ˜ ์ œ๊ณต
#include "addons/RTDBHelper.h"

// Firebase ์„ค์ •
#define FIREBASE_HOST "https://esp32-led-6265e-default-rtdb.firebaseio.com/"  //"https://esp32-light-sensor-49d0d-default-rtdb.firebaseio.com/"
#define FIREBASE_AUTH "AIzaSyDv0Uh_reGxqHVqVVLm8kGGaP1KFIkC0io"  //"AIzaSyDpwhvYS26vq2UowbTusA502vJucotAPMI"
#define WIFI_SSID "zineeh"
#define WIFI_PASSWORD "SMARTDEVICE0516"


// Firebase ๊ฐ์ฒด ์ •์˜
FirebaseData fbdo;
FirebaseAuth auth;
FirebaseConfig config;
bool signupOK = false;

// ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ฃผ ๊ฒฝ๋กœ
String databasePath = "/room1";
String sensorPath = "/lightsensor";
String timePath = "/timestamp";

/// ๋ถ€๋ชจ ๋…ธ๋“œ (ํ˜„์žฌ ์‹œ๊ฐ„ ์ •๋ณด๋กœ ๋งค ๋ฃจํ”„๋งˆ๋‹ค ์—…๋ฐ์ดํŠธ)
String parentPath;

int timestamp;
FirebaseJson json;

const char* ntpServer = "pool.ntp.org";

// ๋น› ์„ผ์„œ ํ•€
int sensorPin = 34;

// ํƒ€์ด๋จธ ๋ณ€์ˆ˜ (์ƒˆ๋กœ์šด ์ธก์ • ๊ฐ’์„ 20์ดˆ๋งˆ๋‹ค ์ „์†ก)
unsigned long sendDataPrevMillis = 0;
unsigned long timerDelay = 60000;  //1 minutes

// WiFi ์ดˆ๊ธฐํ™”
void setup_wifi() {
  delay(10);
  // Wi-Fi ๋„คํŠธ์›Œํฌ์— ์—ฐ๊ฒฐ ์‹œ์ž‘
  Serial.println();
  Serial.print("์—ฐ๊ฒฐ ์ค‘์ธ Wi-Fi: ");
  Serial.println(WIFI_SSID);

  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("Wi-Fi ์—ฐ๊ฒฐ๋จ");
  Serial.println("IP ์ฃผ์†Œ: ");
  Serial.println(WiFi.localIP());
}
// ํ˜„์žฌ epoch ์‹œ๊ฐ„์„ ๊ฐ€์ ธ์˜ค๋Š” ํ•จ์ˆ˜
unsigned long getTime() {
  time_t now;
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    //Serial.println("Failed to obtain time");
    return (0);
  }
  time(&now);
  return now;
}

void setup() {
  Serial.begin(115200);

  // WiFi ์—ฐ๊ฒฐ
  setup_wifi();
  configTime(0, 0, ntpServer);

  // API ํ‚ค ํ• ๋‹น (ํ•„์ˆ˜)
  config.api_key = "AIzaSyDv0Uh_reGxqHVqVVLm8kGGaP1KFIkC0io";

  // RTDB URL ํ• ๋‹น (ํ•„์ˆ˜)
  config.database_url = "https://esp32-led-6265e-default-rtdb.firebaseio.com/";

  Firebase.reconnectWiFi(true);
  fbdo.setResponseSize(4096);

  /* ํšŒ์› ๊ฐ€์ž… */
  if (Firebase.signUp(&config, &auth, "", "")) {
    Serial.println("ok");
    signupOK = true;
  } else {
    Serial.printf("%s\n", config.signer.signupError.message.c_str());
  }

  // ์žฅ๊ธฐ ์‹คํ–‰ ํ† ํฐ ์ƒ์„ฑ ์ž‘์—…์— ๋Œ€ํ•œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ํ• ๋‹น
  config.token_status_callback = tokenStatusCallback;

  // ํ† ํฐ ์ƒ์„ฑ ์ตœ๋Œ€ ์žฌ์‹œ๋„ ํšŸ์ˆ˜ ํ• ๋‹น
  config.max_token_generation_retry = 5;

  // Firebase ์ธ์ฆ ๋ฐ ์„ค์ •๊ณผ ํ•จ๊ป˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ดˆ๊ธฐํ™”
  Firebase.begin(&config, &auth);
}

void loop() {

  // Send new readings to database
  if (Firebase.ready() && signupOK
      && (millis() - sendDataPrevMillis > timerDelay
          || sendDataPrevMillis == 0)) {
    sendDataPrevMillis = millis();

    // ํ˜„์žฌ ํƒ€์ž„์Šคํƒฌํ”„ ๊ฐ€์ ธ์˜ค๊ธฐ
    timestamp = getTime();
    Serial.print("time: ");
    Serial.println(timestamp);

    parentPath = databasePath + "/" + String(timestamp);

    json.set(sensorPath.c_str(), String(analogRead(sensorPin)));
    json.set(timePath, String(timestamp));
    Serial.println("Set json... ");
    if (Firebase.setJSON(fbdo, parentPath.c_str(), json))
      Serial.println("ok");
    else
      Serial.println(fbdo.errorReason());
  }
}
  • ์‹ค์Šต ๊ฒฐ๊ณผ

4-3. Firebase๋ฅผ ํ™œ์šฉํ•œ ๋น› ๊ฐ์ง€ ์„ผ์„œ๊ฐ’ ๋ณ€ํ™”๋Ÿ‰ ์‹ค์‹œ๊ฐ„ ํ™•์ธ

  • ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ ํ›„ ์•ฑ(Light-Sensor-Web-App) ๋“ฑ๋ก ๋ฐ script ๋ณต์‚ฌ
  • ์‹คํ–‰ ์ฝ”๋“œ
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
    <meta http-equiv="Pragma" content="no-cache" />
    <meta http-equiv="Expires" content="0" />
    <title>ESP ๋ฐ์ดํ„ฐ ๊ธฐ๋ก Firebase ์•ฑ</title>
    <style>
        #chart_div {
            width: 1200px;
            height: 500px;
        }

        #gauge_div {
            height: 300px;
        }

        div {
            display: table;
            margin-right: auto;
            margin-left: auto;
        }
    </style>
    <!-- Firebase SDK ํฌํ•จ -->
    <script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-app.js"></script>

    <!-- ํ•„์š”ํ•œ Firebase ๊ธฐ๋Šฅ๋งŒ ํฌํ•จ -->
    <script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-auth.js"></script>
    <script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-database.js"></script>

    <script>
    // ์›น ์•ฑ์˜ Firebase ๊ตฌ์„ฑ
    const firebaseConfig = {
        apiKey: "AIzaSyDv0Uh_reGxqHVqVVLm8kGGaP1KFIkC0io",
        authDomain: "esp32-led-6265e.firebaseapp.com",
        databaseURL: "https://esp32-led-6265e-default-rtdb.firebaseio.com/",
        projectId: "esp32-led-6265e",
        storageBucket: "esp32-led-6265e.appspot.com",
        messagingSenderId: "442137904366",
        appId: "1:442137904366:web:f185f9518c565f4d261fff"
    };

    // Firebase ์ดˆ๊ธฐํ™”
    firebase.initializeApp(firebaseConfig);

    // ์ธ์ฆ๊ณผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ฐธ์กฐ ์ƒ์„ฑ
    const auth = firebase.auth();
    const db = firebase.database();
    </script>
</head>
<body>
    <!-- ์ฐจํŠธ๋ฅผ ์œ„ํ•œ ์ปจํ…Œ์ด๋„ˆ -->
    <div>
        <div id="chart_div"></div>
    </div>
    <div>
        <div id="gauge_div"></div>
    </div>
    <script type="text/javascript"
            src="https://www.gstatic.com/charts/loader.js"></script>
    <script>
        // ํ˜„์žฌ ์ฐจํŠธ ํŒจํ‚ค์ง€ ๋กœ๋“œ
        google.charts.load('current', {
        packages: ['corechart', 'line', 'gauge'],
        });
		    // API๊ฐ€ ๋กœ๋“œ๋˜์—ˆ์„ ๋•Œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ์„ค์ •
    google.charts.setOnLoadCallback(drawChart);

    function drawChart() {
    // ๊ธฐ๋ณธ ๊ฐ’์œผ๋กœ ๋ฐ์ดํ„ฐ ๊ฐ์ฒด ์ƒ์„ฑ
    let data = google.visualization.arrayToDataTable([
    ['Time', 'Light Sensor'],
    ["00:00", 0],
    ]);

    let gauge_data = google.visualization.arrayToDataTable([
    ['Light Sensor'],
    [0],
    ]);

    // ์ œ๋ชฉ, ์ƒ‰์ƒ ๋“ฑ์ด ํฌํ•จ๋œ ์˜ต์…˜ ๊ฐ์ฒด ์ƒ์„ฑ
    let options = {
    max: 2048, //4096,
    hAxis: {
    //textPosition: 'none',
    },
    vAxis: {

    },
    };

    // ์ฐจํŠธ ๊ทธ๋ฆฌ๊ธฐ
    let chart = new google.visualization.LineChart(
    document.getElementById('chart_div')
    );
    chart.draw(data, options);

    let gauge_chart = new google.visualization.Gauge(
        document.getElementById('gauge_div')
    );
    gauge_chart.draw(gauge_data, options);

    // ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฒฝ๋กœ
    var dbPath = 'room1';

    // ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ฐธ์กฐ
    var dbRef = firebase.database().ref(dbPath);

    // ํ‘œ์‹œํ•  ์ตœ๋Œ€ ๋ฐ์ดํ„ฐ ํ–‰ ์ˆ˜
    let maxDatas = 50;

    // ์ตœ์‹  ์ธก์ •๊ฐ’ ๊ฐ€์ ธ์™€์„œ ์ฐจํŠธ์— ํ‘œ์‹œ (ํ‘œ์‹œ๋˜๋Š” ์ธก์ •๊ฐ’ ์ˆ˜๋Š” chartRange ๊ฐ’์— ํ•ด๋‹น)
    dbRef.orderByKey().limitToLast(maxDatas).on('child_added', snapshot =>{
    var jsonData = snapshot.toJSON(); // ์˜ˆ: {lightsensor: 2502, timestamp:1641317355}

    // ๊ฐ’ ์ €์žฅ
    var lightsensor = Number(jsonData.lightsensor);
    var timestamp = epochToDateTime(jsonData.timestamp);

    // ์ฐจํŠธ์— ๊ฐ’ ํ‘œ์‹œ
    if (data.getNumberOfRows() > maxDatas) {
    data.removeRows(0, data.getNumberOfRows() - maxDatas);
    }
    data.addRow([timestamp, lightsensor]);
    chart.draw(data, options);

    gauge_data.setValue(0, 0, lightsensor);
    gauge_chart.draw(gauge_data, options);
    });
    }
    // ์—ํฌํฌ Time์„ JavaScript Date ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜
    function epochToJsDate(epochTime){
    return new Date(epochTime*1000);
    }

    // Time์„ ์‚ฌ๋žŒ์ด ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ํ˜•์‹ (HH:MM)์œผ๋กœ ๋ณ€ํ™˜
    function epochToDateTime(epochTime) {
    var epochDate = new Date(epochToJsDate(epochTime));
    var dateTime =
    ("00" + epochDate.getHours()).slice(-2) +
    ":" +
    ("00" + epochDate.getMinutes()).slice(-2);
    return dateTime;
    }
    </script>
</body>
</html>
  • ์‹ค์Šต ๊ฒฐ๊ณผ
  • ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ณ€ํ™”ํ•˜๋Š” ๋ฐ์ดํ„ฐ ๊ทธ๋ž˜ํ”„(๋ฐ์ดํ„ฐ ๋ถ„์„ ๊ธฐ๋Šฅ ๊ตฌํ˜„)
  • ๋น›์˜ ์ •๋„๊ฐ€ ๊ฐ€์žฅ ๋†’์•˜๋˜ ์‹œ๊ฐ„๊ณผ ์ˆ˜์น˜๊ฐ’ ํ™•์ธ ๊ฐ€๋Šฅ 11์ฃผ์ฐจ 7-4(3)

4-4. 4-3 ์‹ค์Šต์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ Firebase ์›น ํ˜ธ์ŠคํŒ…

  • Firebase ์›น ์•ฑ์„ url์„ ํ†ตํ•ด ์กฐํšŒ ๊ฐ€๋Šฅ
  • https://firebase.google.com/docs/cli?hl=ko ์—์„œ CLI ์„ค์น˜ ๋ฐ ํ”„๋กฌํ”„ํŠธ ์‚ฌ์šฉ

11์ฃผ์ฐจ 7-4-1

  • ๋ช…๋ น์–ด ์‹คํ–‰ ํ›„ ํ”„๋กœ์ ํŠธ ๋ฆฌ์ŠคํŠธ ํ™•์ธ 11์ฃผ์ฐจ 7-4-1(2)

  • ๋ช…๋ น์–ด ์‹คํ–‰ ํ›„ ํ”„๋กœ์ ํŠธ ๋ฐ hosting ์„ค์ •

11์ฃผ์ฐจ 7-4-1(3)

  • ๋ช…๋ น์–ด ์‹คํ–‰ ํ›„ ์›น ์•ฑ ํ˜ธ์ŠคํŒ… ์‹œ์ž‘

11์ฃผ์ฐจ 7-4-1(4)

  • ์‹ค์Šต ๊ฒฐ๊ณผ
  • ๋ณต์‚ฌํ•œ url์„ ๋ธŒ๋ผ์šฐ์ €์— ์ž…๋ ฅํ•˜๋ฉด ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋น› ์„ผ์„œ ๊ฐ’์„ ๋ชจ๋‹ˆํ„ฐ๋ง ๊ฐ€๋Šฅ

11์ฃผ์ฐจ 7-4-1(5)

  • ์• ํ”Œ์˜ safari์—์„œ๋„ ํ™•์ธ ๊ฐ€๋Šฅ 11์ฃผ์ฐจ 7-4-1(6)

5. ๋น› ์„ผ์„œ

5-1. ํฌํ† TR: ํฌํ† ๋‹ค์ด์˜ค๋“œ์˜ PN ์ ‘ํ•ฉ์„ ๋ฒ ์ด์Šค-์ด๋ฏธํ„ฐ ์ ‘ํ•ฉ์— ์ด์šฉํ•œ ํŠธ๋žœ์ง€์Šคํ„ฐ๋กœ ๋น›์—๋„ˆ์ง€๋ฅผ ์ „๊ธฐ์—๋„ˆ์ง€๋กœ ๋ณ€ํ™˜
     - ๋น›์˜ ์„ธ๊ธฐ์— ๋”ฐ๋ผ ํ๋ฅด๋Š” ์ „๋ฅ˜๊ฐ€ ๋ณ€ํ™”ํ•˜๋Š” ๊ด‘๊ธฐ์ „๋ ฅ ํšจ๊ณผ๋ฅผ ์ด์šฉํ•จ
     - ๊ด‘์ „๋ฅ˜๋ฅผ ํŠธ๋žœ์ง€์Šคํ„ฐ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ฆํญ์‹œํ‚ด
     - pnpํ˜•(๊ฒŒ๋ฅด๋งˆ๋Š„ ์‚ฌ์šฉ), npnํ˜•(์‹ค๋ฆฌ์ฝ˜ ์‚ฌ์šฉ)
     - ํฌํ† TR์€ ํฌํ† ๋‹ค์ด์˜ค๋“œ๋ณด๋‹ค ๋น›์— ๋” ๋ฏผ๊ฐํ•˜์ง€๋งŒ ๋ฐ˜์‘ ์†๋„๋Š” ๋” ๋А๋ฆผ

5-2. ํฌํ† ๋‹ค์ด์˜ค๋“œ: ๊ด‘๊ธฐ์ „๋ ฅ ํšจ๊ณผํ˜• ๋‹ค์ด์˜ค๋“œ์— ์™ธ๋ถ€ํšŒ๋กœ๋ฅผ ์ ‘์†ํ•˜์—ฌ ๋น›์„ ๋น„์ถฐ ๊ด‘์ „๋ฅ˜๋ฅผ ๊บผ๋‚ด๋Š” ์„ผ์„œ
     - ๊ด‘์‹ ํ˜ธ๋ฅผ ์ „๊ธฐ์‹ ํ˜ธ๋กœ ๋ณ€ํ™˜

5-3. CDS: ์กฐ๋„ ์„ผ์„œ(ํ™ฉํ™” ์นด๋“œ๋ฎด ๊ด‘์„ผ์„œ)์ด๋ฉฐ ๋น›์˜ ์–‘์— ๋”ฐ๋ผ ์ €ํ•ญ๊ฐ’์ด ๋ณ€ํ™”(๋น›์˜ ์„ธ๊ธฐ๊ฐ€ ์…€์ˆ˜๋ก ์ €ํ•ญ์ด ์ž‘์•„์ง)ํ•˜๋Š” ๊ด‘ ๊ฐ€๋ณ€์ €ํ•ญ
     - ๊ด‘์„ผ์„œ ์ค‘ ๊ฐ€์žฅ ๊ฐ„๋‹จํ•˜๊ณ  ์ €๋ ดํ•˜์—ฌ ์ผ์ƒ์ƒํ™œ์— ๋งŽ์ด ์“ฐ์ž„

6. ์ฐธ๊ณ ์‚ฌํ•ญ

โš ๏ธ **GitHub.com Fallback** โš ๏ธ