๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Today I Learned(TIL)/์ŠคํŒŒ๋ฅดํƒ€ ๋‚ด์ผ๋ฐฐ์›€์บ ํ”„

์›น ๊ฐœ๋ฐœ ์ข…ํ•ฉ_5์ฃผ์ฐจ

by carrot0911 2024. 11. 1.

์›น ๊ฐœ๋ฐœ 5์ฃผ์ฐจ์— ๋ฐฐ์šด ๋‚ด์šฉ

์ŠคํŒŒ๋ฅดํƒ€ํ”Œ๋ฆญ์Šค

์ŠคํŒŒ๋ฅดํƒ€ํ”Œ๋ฆญ์Šค ํ”„๋กœ์ ํŠธ๋ฅผ ์ด์šฉํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ Firestore Database์— ๋„ฃ๊ณ  ๋‹ค์‹œ ๊ฐ€์ ธ์˜ค๋Š” ๋‚ด์šฉ์„ ๋ณต์Šตํ–ˆ๋‹ค ๐Ÿคจ๐Ÿคจ 

Firebase ์—ฐ๋™ ๊ธฐ๋ณธ ์„ธํŒ…

๋จผ์ € Firebase ์—ฐ๋™์„ ์œ„ํ•œ ๊ธฐ๋ณธ ์„ธํŒ… ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์—ˆ๋‹ค!

// Firebase SDK ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ฐ€์ ธ์˜ค๊ธฐ
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-app.js";
import { getFirestore } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-firestore.js";
import { collection, addDoc } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-firestore.js";
import { getDocs } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-firestore.js";

// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
    apiKey: "",
    authDomain: "",
    projectId: "",
    storageBucket: "",
    messagingSenderId: "",
    appId: "",
    measurementId: ""
};

// Firebase ์ธ์Šคํ„ด์Šค ์ดˆ๊ธฐํ™”
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);

์˜ํ™” ๋ฐ์ดํ„ฐ ๋„ฃ๊ธฐ - addDoc

๊ทธ ๋‹ค์Œ ์ž…๋ ฅํ•œ ์˜ํ™” ๋ฐ์ดํ„ฐ๋ฅผ Firestore Database์— ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•ด์ฃผ์—ˆ๋‹ค!

$("#postingbtn").click(async function () {  //๋ฒ„ํŠผ์˜ id๋ฅผ ๋„ฃ์–ด์„œ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ์ž‘๋™๋˜๋Š” ํ•จ์ˆ˜ ์ž‘์„ฑ!
    let image = $('#image').val();
    let title = $('#title').val();
    let star = $('#star').val();  //select๋กœ ์ด๋ฃจ์–ด์ง„ ๋ถ€๋ถ„์—์„œ๋Š” value์— ์žˆ๋Š” ๊ฐ’์„ ์ถœ๋ ฅํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์ถœ๋ ฅํ•˜๊ณ  ์‹ถ์€ ๊ฐ’์œผ๋กœ value ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ฉด ๋œ๋‹ค!
    let comment = $('#comment').val();

    let doc = {  //๋ฐ์ดํ„ฐ๋“ค์„ ๋ณ€์ˆ˜์— ํ•˜๋‚˜์”ฉ ๋‹ด์•„์ฃผ๊ธฐ!
        'image': image,
        'title': title,
        'star': star,
        'comment': comment
    };
    
    await addDoc(collection(db, "movies"), doc);  //PostBox์— ์ž…๋ ฅํ–ˆ๋˜ ๊ฐ’๋“ค์„ Database์— ์ถ”๊ฐ€ํ•˜๊ธฐ!
    alert('์ €์žฅ ์™„๋ฃŒ!');  //ํŒ์—… ์ฐฝ์„ ํ‘œ์‹œํ•˜์—ฌ ์ €์žฅ์ด ์™„๋ฃŒ๋˜์—ˆ์Œ์„ ํ‘œ์‹œ!
    window.location.reload();  //ํ˜„์žฌ ํŽ˜์ด์ง€ ์ƒˆ๋กœ๊ณ ์นจ
})

Firestore Database์—์„œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ - getDocs

Firestore Database์— ์ €์žฅ๋˜์–ด ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋“ค์„ ๋ˆˆ์— ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ๊ฐ€์ ธ์˜ค๋Š” ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ์—ˆ๋‹ค!

let docs = await getDocs(collection(db, "movies"));
docs.forEach((doc) => {
    let row = doc.data();

    let image = row['image'];
    let title = row['title'];
    let star = row['star'];  //select๋กœ ์ด๋ฃจ์–ด์ง„ ๋ถ€๋ถ„์—์„œ๋Š” value์— ์žˆ๋Š” ๊ฐ’์„ ์ถœ๋ ฅํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์ถœ๋ ฅํ•˜๊ณ  ์‹ถ์€ ๊ฐ’์œผ๋กœ value ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ฉด ๋œ๋‹ค!
    let comment = row['comment'];

    //console.log(image, title, comment);  //console ์ฐฝ์— ๊ฐ’ ๋„์šฐ๊ธฐ!
    //console.log(star);  //console ์ฐฝ์— ๊ฐ’ ๋„์šฐ๊ธฐ!

    let temp_html = `            
    <div class="col">
        <div class="card h-100">
            <img src="${image}"
                class="card-img-top" alt="...">
            <div class="card-body">
                <h5 class="card-title">${title}</h5>
                <p class="card-text">${star}</p>
                <p class="card-text">${comment}</p>
            </div>
        </div>
    </div>`;

    $('#card').append(temp_html);  //์นด๋“œ ์ถ”๊ฐ€ํ•˜๊ธฐ!

});

 

๋ฐฐํฌ

์†Œํ”„ํŠธ์›จ์–ด ๊ฐœ๋ฐœ ๊ณผ์ •์—์„œ ๊ฐœ๋ฐœํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜, ์›น์‚ฌ์ดํŠธ, ์„œ๋น„์Šค ๋“ฑ์„ ์‹ค์ œ ์‚ฌ์šฉ์ž๋“ค์—๊ฒŒ ์ œ๊ณตํ•˜๋Š” ๊ณผ์ •์„ ๋งํ•œ๋‹ค.
์ฆ‰, ๋งŒ๋“  ์ž‘์—…๋ฌผ์„ ์™ธ๋ถ€์— ๊ณต๊ฐœํ•˜๋Š” ์ผ์ด๋‹ค!! ๋งํฌ๊ฐ€ ์ƒ๊ฒจ์„œ ์š”์ฒญํ•˜๋ฉด ๊ฒฐ๊ณผ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋Š” ์„œ๋น„์Šค๋ฅผ ๋‚ด๋†“๋Š” ์ผ์ด๋‹ค!

URL - Uniform Resource Locator

์ธํ„ฐ๋„ท์—์„œ ํŠน์ • ๋ฆฌ์†Œ์Šค์˜ ์œ„์น˜๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ฃผ์†Œ์ด๋‹ค. ๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ, ์›น ํŽ˜์ด์ง€๋‚˜ ํŒŒ์ผ์˜ ๊ณ ์œ ํ•œ ์ฃผ์†Œ์ด๋‹ค!

ํ”„๋กœํ† ์ฝœ://๋„๋ฉ”์ธ/๊ฒฝ๋กœ
  • ํ”„๋กœํ† ์ฝœ(protocol) : ์›น ๋ธŒ๋ผ์šฐ์ €์™€ ์›น ์„œ๋ฒ„ ๊ฐ„์˜ ํ†ต์‹  ๋ฐฉ์‹์„ ์ง€์ •ํ•œ๋‹ค. ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ํ”„๋กœํ† ์ฝœ์€ "http://"์™€ "https://"์ด๋‹ค.
  • ๋„๋ฉ”์ธ(domain) : ์ธํ„ฐ๋„ท ์ƒ์—์„œ ๊ณ ์œ ํ•œ ์‹๋ณ„์ž๋กœ ์‚ฌ์šฉ๋˜๋Š” ์›น ์‚ฌ์ดํŠธ์˜ ์ฃผ์†Œ์ด๋‹ค. ๋„๋ฉ”์ธ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์ดํŠธ์˜ ์ด๋ฆ„๊ณผ ์ตœ์ƒ์œ„ ๋„๋ฉ”์ธ(Top-Level Domain)์œผ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.
  • ๊ฒฝ๋กœ(path) : ์›น ์‚ฌ์ดํŠธ ๋‚ด์—์„œ ํŠน์ • ํŽ˜์ด์ง€๋‚˜ ํŒŒ์ผ์˜ ์œ„์น˜๋ฅผ ์ง€์ •ํ•œ๋‹ค. ๊ฒฝ๋กœ๋Š” ์Šฌ๋ž˜์‰ฌ(/)๋กœ ๊ตฌ๋ถ„๋œ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ์™€ ํŒŒ์ผ๋ช…์œผ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.
ex) https://spartacodingclub.kr/catalog

์˜ˆ๋ฅผ ๋“ค์–ด, https://spartacodingclub.kr/catalog ๋ผ๋Š” URL์€ HTTPS ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•˜๋ฉฐ, 
spartacodingclub.kr ๋ผ๋Š” ๋„๋ฉ”์ธ์— ์œ„์น˜ํ•œ catalog๋ผ๋Š” ๊ฒฝ๋กœ์— ์žˆ๋Š” ํŽ˜์ด์ง€๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

 

Github Pages๋กœ ๋ฐฐํฌํ•˜๊ธฐ

Github Pages

Github์—์„œ ์ œ๊ณตํ•˜๋Š” ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์ธํ„ฐ๋„ท์œผ๋กœ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋Š” ์„œ๋น„์Šค์ด๋‹ค.

โœ”๏ธ์ฐธ๊ณ  - ์ •์  ์›น ํŽ˜์ด์ง€

์‹ค์‹œ๊ฐ„ ๋ณ€๊ฒฝ๋˜๋Š” ๋‚ด์šฉ์€ ์—†๊ณ  HTML, CSS, JavaScript ๋“ฑ์œผ๋กœ ์ด๋ฃจ์–ด์ง„ ๋‹จ์ˆœํ•œ ์›น ํŽ˜์ด์ง€๋ฅผ ์˜๋ฏธํ•œ๋‹ค.
Girhub Pages๋ฅผ ์ด์šฉํ•˜์—ฌ ์ž์‹ ์˜ ํ”„๋กœ์ ํŠธ๋ฅผ ์˜จ๋ผ์ธ์œผ๋กœ ํ˜ธ์ŠคํŒ…ํ•˜์—ฌ ์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ ‘์† ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค!

์ €์žฅ์†Œ ์ƒ์„ฑํ•˜๊ธฐ

create Repository๋ฅผ ์„ ํƒํ•˜๊ณ  ์ €์žฅ์†Œ ์ด๋ฆ„ ์ž…๋ ฅ ํ›„, public์„ ์„ ํƒํ•˜๊ณ  Create Repository๋ฅผ ํด๋ฆญํ•œ๋‹ค!

ํŒŒ์ผ ์—…๋กœ๋“œํ•˜๊ธฐ

Uploading Existing Files๋ฅผ ์„ ํƒํ•˜๊ณ  choose your files๋ฅผ ๋ˆ„๋ฅธ ํ›„ ํŒŒ์ผ ์„ ํƒํ•ด์„œ ์—…๋กœ๋“œํ•œ๋‹ค!

๋ฐฐํฌํ•˜๊ธฐ

์ €์žฅ์†Œ์—์„œ settings๋กœ ๋“ค์–ด๊ฐ€๊ณ  ํ™”๋ฉด ์™ผ์ชฝ์—์„œ Pages๋ฅผ ์ฐพ์•„์„œ ๋“ค์–ด๊ฐ„๋‹ค.
Branch Name์„ main์œผ๋กœ ์„ค์ •ํ•˜๊ณ  save ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์กฐ๊ธˆ์˜ ๊ธฐ๋‹ค๋ฆผ ํ›„ ์ƒˆ๋กœ๊ณ ์นจ ์‹œ ํ™”๋ฉด์— ์ฃผ์†Œ๊ฐ€ ๋…ธ์ถœ๋œ๋‹ค ๐Ÿ˜ฎ๐Ÿ˜ฎ๐Ÿ˜ฎ

 

๋ฐฐํฌํ•œ ๊ฒƒ ์ˆ˜์ •ํ•˜๊ธฐ & ์ฃผ์˜ ์‚ฌํ•ญ

์ˆ˜์ •ํ•˜๊ธฐ

VS Code์—์„œ ์ž‘์„ฑํ•ด์„œ ์ „์ฒด ์ฝ”๋“œ๋ฅผ ๊ต์ฒดํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค!
Github์—์„œ ์ˆ˜์ •ํ•  ๊ฒฝ์šฐ ์˜ค๋ฅ˜๊ฐ€ ๋‚  ํ™•๋ฅ ์ด ๋†’๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค!!

์‚ญ์ œ ํ›„ ์ˆ˜์ •๋œ ํŒŒ์ผ์„ ์˜ฌ๋ฆด ๋•Œ๋Š” ์‚ญ์ œํ•˜๊ณ  ์‹ถ์€ ํ”„๋กœ์ ํŠธ์— repository๋กœ ๋“ค์–ด๊ฐ€์„œ ์‚ญ์ œํ•˜๊ณ  ์‹ถ์€ ํŒŒ์ผ ์„ ํƒ ํ›„ Delete file์„ ํด๋ฆญํ•˜๋ฉด ์‚ญ์ œ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค. 
์‚ญ์ œ๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด Commit changes๋ฅผ ๋ˆŒ๋Ÿฌ์ฃผ๊ณ  ํŒŒ์ผ ์‚ญ์ œ ํ™•์ธํ•œ ๋‹ค์Œ Add file์„ ์„ ํƒ ํ›„ ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•˜๋ฉด ๋œ๋‹ค!

์ฃผ์˜ ์‚ฌํ•ญ๐Ÿคจ๐Ÿคจ

  • ๋ฐฐํฌํ•˜๊ธฐ ์ „์— ๋ฐ˜๋“œ์‹œ ๋กœ์ปฌ์—์„œ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•œ๋‹ค! ๋ฐฐํฌ๋œ ํŽ˜์ด์ง€์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋œ๋‹ค!
  • ์›๊ฒฉ ์ €์žฅ์†Œ์—๋Š” ์ค‘์š”ํ•œ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•˜๊ธฐ!!
    ๋น„๋ฐ€๋ฒˆํ˜ธ, API ํ‚ค, ๊ฐœ์ธ์ •๋ณด ๋“ฑ ๋ฏผ๊ฐํ•œ ์ •๋ณด๋Š” ์†Œ์Šค ์ฝ”๋“œ์—์„œ ์ œ๊ฑฐํ•ด์•ผ ํ•œ๋‹ค!!!

 

Firebase์˜ ํ•œ๊ณ„์ 

Firebase๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ํ˜ธ์ŠคํŒ…ํ•˜๋ฉด ํŽธ๋ฆฌํ•จ๊ณผ ๋น ๋ฅธ ๊ฐœ๋ฐœ ์†๋„๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์ง€๋งŒ, ์ผ๋ถ€ ์ œํ•œ ์‚ฌํ•ญ์ด ์กด์žฌํ•œ๋‹ค.

  • ์„œ๋ฒ„ ์ œ์–ด ์ œํ•œ : Firebase๋Š” ์„œ๋ฒ„ ์ธํ”„๋ผ์— ๋Œ€ํ•œ ์ง์ ‘์ ์ธ ์ปจํŠธ๋กค์ด ์ œํ•œ๋œ๋‹ค. Firebase์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ๊ณผ ๋ฐฉ์‹์— ๋”ฐ๋ผ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•œ๋‹ค....
  • ํ™•์žฅ์„ฑ ์ œํ•œ : Firebase ๊ทœ๋ชจ์— ๋”ฐ๋ฅธ ๊ฐ€๋กœ ํ™•์žฅ์„ฑ ์ธก๋ฉด์—์„œ ์ œํ•œ์ด ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค.
  • ์ข…์†์„ฑ : Firebase๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Google์˜ ์„œ๋น„์Šค์— ์˜์กดํ•˜๊ฒŒ ๋œ๋‹ค. Firebase ์™ธ๋ถ€์˜ ๋‹ค๋ฅธ ์„œ๋น„์Šค๋‚˜ ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•˜๊ธฐ ์–ด๋ ต๊ฑฐ๋‚˜ ์ œํ•œ์ ์ผ ์ˆ˜ ์žˆ๋‹ค.....

์˜ˆ์‹œ

  • Firebase ๋ถ•์–ด๋นต ๊ฐ€๊ฒŒ :
    ํŒŒ์ด์–ด๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ด๋ฆฐ ๋ถ•์–ด๋นต ๊ฐ€๊ฒŒ๋Š” ๋งค์šฐ ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ํŒŒ์ด์–ด๋ฒ ์ด์Šค๋Š” ์ด๋ฏธ ๋ถ•์–ด๋นต์„ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ธฐ๊ณ„๋ฅผ ๊ฐ–์ถ”๊ณ  ์žˆ์œผ๋ฉฐ, ์†๋‹˜๋“ค์€ ๋‹ค์–‘ํ•œ ๋ง›๊ณผ ํฌ๊ธฐ์˜ ๋ถ•์–ด๋นต์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ถ•์–ด๋นต ๊ฐ€๊ฒŒ ์ฃผ์ธ์€ ํŒŒ์ด์–ด๋ฒ ์ด์Šค์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ๊ณผ ๋ฐฉ์‹์— ๋”ฐ๋ผ์„œ๋งŒ ๋ถ•์–ด๋นต์„ ์ œ์กฐํ•˜๊ณ  ํŒ๋งคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋‹ค๋ฅธ ๊ฐœ๋ฐœ ํ”Œ๋žซํผ ๋ถ•์–ด๋นต ๊ฐ€๊ฒŒ : 
    ๋ฐ˜๋ฉด์— ๋‹ค๋ฅธ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ด๋ฆฐ ๋ถ•์–ด๋นต ๊ฐ€๊ฒŒ๋Š” ๋” ๋‹ค์–‘ํ•œ ๊ฐ€๋Šฅ์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ฃผ์ธ์€ ์ž์‹ ๋งŒ์˜ ๊ณ ์œ ํ•œ ๋ถ•์–ด๋นต ๋ ˆ์‹œํ”ผ๋ฅผ ๊ฐœ๋ฐœํ•˜๊ณ , ๋ถ•์–ด๋นต ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ ์š”๋ฆฌ๋„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ฃผ์ธ์€ ์ž์œ ๋กญ๊ฒŒ ๊ฐ€๊ฒŒ๋ฅผ ์šด์˜ํ•˜๊ณ , ์š”๋ฆฌ๋ฅผ ๋‹ค์–‘ํ™”ํ•˜์—ฌ ๋‹ค๋ฅธ ๋ง›๊ณผ ์ œํ’ˆ์„ ์†๋‹˜๋“ค์—๊ฒŒ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํŒŒ์ด์ฌ์˜ ์‚ฌ์šฉ

  • ํŒŒ์ด์ฌ์€ ๋‹ค์–‘ํ•œ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ ๊ฐ€๋Šฅ์„ฑ์„ ์ œ๊ณตํ•˜๋ฉฐ, ๊ฐœ๋ฐœ์ž๊ฐ€ ์›ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์„œ๋ฒ„๋ฅผ ๊ตฌ์ถ•ํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.
  • ํŒŒ์ด์ฌ์€ ์„œ๋ฒ„์— ๋Œ€ํ•œ ์™„์ „ํ•œ ์ปจํŠธ๋กค์„ ๊ฐ–๊ฒŒ ๋œ๋‹ค. ์ฃผ์ธ์€ ์ž์‹ ๋งŒ์˜ ๊ณ ์œ ํ•œ ๋ฐฉ์‹์œผ๋กœ ์„œ๋ฒ„๋ฅผ ๊ตฌ์ถ•ํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํŒŒ์ด์ฌ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, ์„œ๋ฒ„์˜ ํ™•์žฅ์„ฑ์„ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํ•„์š”์— ๋”ฐ๋ผ ๋ฆฌ์†Œ์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” ๋Œ€๊ทœ๋ชจ ๊ธฐ์—…์ด๋‚˜ ๋งŽ์€ ํŠธ๋ž˜ํ”ฝ์„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š” ํ”„๋กœ์ ํŠธ์—์„œ ์ค‘์š”ํ•œ ์š”์†Œ์ด๋‹ค.
  • ํŒŒ์ด์ฌ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, ๋‹ค๋ฅธ ์„œ๋น„์Šค์™€์˜ ํ†ตํ•ฉ์ด๋‚˜ ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๋”์šฑ ์œ ์—ฐํ•˜๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

5์ฃผ์ฐจ ์ˆ™์ œ - Javascript๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋™์  ๋ฐ์ดํ„ฐ ์ƒ์„ฑํ•˜๊ธฐ

4์ฃผ์ฐจ, 5์ฃผ์ฐจ์—์„œ ๋ฐฐ์šด ๋‚ด์šฉ๋“ค์„ ํ™œ์šฉํ•˜์—ฌ ์ œ๊ณต๋œ ์ฝ”๋“œ ์ค‘ ๋นˆ ๋ถ€๋ถ„์„ ์ฑ„์šฐ๋Š” ์ˆ™์ œ์˜€๋‹ค.
๋ง‰ ๊ฐ•์˜๋ฅผ ๋“ค์€ ํ›„๋ผ์„œ ์ž์‹ ๊ฐ ์žˆ๊ฒŒ ์ˆ™์ œ ํŒŒ์ผ์„ ๋‹ค์šด๋ฐ›๊ณ  ์ฝ”๋“œ๋ฅผ ์—ด์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ƒˆ๋กœ์šด ์ฝ”๋“œ๋ฅผ ๋งˆ์ฃผํ•˜๋‹ˆ๊นŒ ์ ์  ๋‚ด ์ž์‹ ์ด ํ—ค๋งค๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๋Š๋ผ๊ณ  ์ฐจ๊ทผ์ฐจ๊ทผ ํ•˜๋‚˜์”ฉ ํ•ด๊ฒฐํ•ด๋‚˜๊ฐ”๋‹ค....

๋จผ์ € Firestore Database์™€ ์—ฐ๋™ํ•˜๊ธฐ ์œ„ํ•œ ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์—ˆ๋‹ค.

<script type="module">
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-app.js";
import { getFirestore } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-firestore.js";
import { collection, addDoc } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-firestore.js";
import { getDocs } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-firestore.js";

const firebaseConfig = {
    // https://firebase.google.com/?hl=ko
    // ํŒŒ์ด์–ด๋ฒ ์ด์Šค์— ์ ‘์†ํ•œ ํ›„ ํ”„๋กœ์ ํŠธ ์„ค์ •์— ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.
    // ๋ณธ์ธ firebaseConfig ๋‚ด์šฉ์œผ๋กœ ์„ค์ •ํ•ด ์ค๋‹ˆ๋‹ค.
    apiKey: "",
    authDomain: "",
    projectId: "",
    storageBucket: "",
    messagingSenderId: "",
    appId: "",
    measurementId: ""
};

const app = initializeApp(firebaseConfig);
const db = getFirestore(app);

์ด ๋ถ€๋ถ„์€ ์ž‘์„ฑํ•  ๋•Œ๋งˆ๋‹ค ๋‹ค๋ฅธ ์ฝ”๋“œ์—์„œ ๋ณต์‚ฌํ•ด์„œ ์‚ฌ์šฉํ•˜๋ผ๊ณ  ํ•˜์…จ๋˜ ๊ฐ•์‚ฌ๋‹˜์˜ ๋ง์„ ๋– ์˜ฌ๋ ค ๋ฐ”๋กœ ์ง์ „์— ์ง„ํ–‰ํ–ˆ๋˜ ์ŠคํŒŒ๋ฅดํƒ€ํ”Œ๋ฆญ์Šค ํ”„๋กœ์ ํŠธ์˜ ์ฝ”๋“œ์—์„œ ๋ณต์‚ฌํ•ด์„œ ๊ฐ€์ ธ์™”๋‹ค ๐Ÿ˜Ž๐Ÿ˜Ž
์—ฐ๋™ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅ ํ›„ ํŽ˜์ด์ง€์— ์ž…๋ ฅํ•œ ๋‚ด์šฉ์„ Database์— ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ–ˆ๋‹ค. ๊ธฐ๋ณธ ํ‹€์€ ์ž‘์„ฑ๋˜์–ด ์žˆ์—ˆ๊ณ  ์•ˆ์— ๋‚ด์šฉ๋ฌผ๋งŒ ์ž…๋ ฅํ•˜๋ฉด ๋๋Š”๋ฐ.. ํ•„์š”ํ•œ ๋ณ€์ˆ˜๋ฅผ ์ฝ”๋“œ์—์„œ ์ฐพ์•„์„œ ์ „์ฒด ์ฝ”๋“œ๋ฅผ ์™„์„ฑํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 <div class="post" id="input-card">
    <div class="form-floating mb-3">
        <input type="email" class="form-control" id="floatingInput" placeholder="name@example.com">
        <label for="floatingInput">์Œ์‹ ์ด๋ฏธ์ง€ ์ฃผ์†Œ</label>
    </div>
    <div class="form-floating mb-3">
        <input type="text" class="form-control" id="foodTitle" placeholder="์˜ํ™” ์ œ๋ชฉ">
        <label for="foodTitle">์Œ์‹๋ช…</label>
    </div>

    <div class="input-group mb-3">
        <button class="btn btn-outline-secondary" type="button">๋ณ„์ </button>
        <select class="form-select" id="inputGroupSelect03"
            aria-label="Example select with button addon">
            <option selected>๋ณ„์  ์„ ํƒ</option>
            <option value="1">โญ</option>
            <option value="2">โญโญ</option>
            <option value="3">โญโญโญ</option>
            <option value="4">โญโญโญโญ</option>
            <option value="5">โญโญโญโญโญ</option>
        </select>
    </div>
    <div class="form-floating">
        <textarea class="form-control" placeholder="Leave a comment here"
            id="floatingTextarea"></textarea>
        <label for="floatingTextarea">์ถ”์ฒœ ์ด์œ </label>
    </div>
    <div class="button2">
        <button type="button" class="btn btn-danger" id="addBtn"> ๊ธฐ๋กํ•˜๊ธฐ </button>
    </div>
</div>

์œ„ ์ฝ”๋“œ์—์„œ ํ•„์š”ํ•œ id๋“ค์„ ์ฐพ์•˜๊ณ  id๋ฅผ ํ™œ์šฉํ•ด์„œ ์ฝ”๋“œ๋ฅผ ์™„์„ฑํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค ๐Ÿ˜ƒ๐Ÿ˜ƒ
๊ทผ๋ฐ ์—ฌ๊ธฐ์„œ ํ•˜๋‚˜์˜ ๋ฌธ์ œ์ ์ด ์žˆ์—ˆ๋Š”๋ฐ......
๋ฐ”๋กœ ๊ฐ•์˜์—์„œ ์ž‘์„ฑํ–ˆ๋˜ ์ฝ”๋“œ์™€ ์ˆ™์ œ์—์„œ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋Š” ์ฝ”๋“œ์˜ ๊ตฌ์กฐ๊ฐ€ ๋‹ฌ๋ž๋‹ค ๐Ÿ˜ฎ๐Ÿ˜ฎ๐Ÿ˜ฎ ์ฒ˜์Œ์— ๋ณด๊ณ  ๋‹นํ™ฉํ–ˆ์ง€๋งŒ ์ฝ”๋“œ์— ์ ํ˜€์žˆ๋Š” ์ฃผ์„์„ ์ฐธ๊ณ ํ•˜๊ณ  try, catch(์˜ˆ์™ธ ์ฒ˜๋ฆฌ) ๋‚ด์šฉ์„ chatgpt๋ฅผ ํ†ตํ•ด ํ•ด๊ฒฐํ•œ ํ›„ ํ•˜๋‚˜ํ•˜๋‚˜ ์ ๊ณ  ๋‚˜๋‹ˆ Firestore Database์— ์ •์ƒ์ ์œผ๋กœ ์ €์žฅ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

$("#addBtn").click(async function () {

    // title_input, comment_input, image_input id๋ฅผ ๊ฐ€์ง„ HTML ์š”์†Œ์—์„œ ๊ฐ’์„ ๊ฐ€์ ธ์™€์„œ title, comment, image ๋ณ€์ˆ˜์— ์ €์žฅํ•ด ์ฃผ์„ธ์š”.
    let image = $('#floatingInput').val();
    let title = $('#foodTitle').val();
    let comment = $('#floatingTextarea').val();
    let star = $('#inputGroupSelect03').val();

    try {
        const docRef = await addDoc(collection(db, "foods"), {

            // ๊ฐ๊ฐ ๋‹ด์€ ๋ณ€์ˆ˜๋ฅผ ์ปฌ๋ ‰์…˜ ํ•„๋“œ์— title, comment, image์— ๊ฐ๊ฐ ๋„ฃ์–ด์ฃผ์„ธ์š”.
            'image': image,
            'title': title,
            'comment': comment,
            'star': star
        });

        alert("์Œ์‹์ด ์ถ”๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!");
        window.location.reload();
    } catch (e) {
        console.error("Error adding document: ", e);
    }
});

๊ทธ ๋‹ค์Œ์€ ์ด์ œ ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋“ค์„ ์šฐ๋ฆฌ ๋ˆˆ์— ๋ณผ ์ˆ˜ ์žˆ๋„๋ก Database์—์„œ ๋‹ค์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ฐจ๋ก€์˜€๋‹ค. ์ด ๋ถ€๋ถ„ ๋˜ํ•œ ๊ธฐ๋ณธ ํ‹€์€ ์ž‘์„ฑ๋˜์–ด ์žˆ์—ˆ๊ณ , ์ค‘์š”ํ•œ ๋ถ€๋ถ„๋งŒ ๋‚ด๊ฐ€ ์ฑ„์›Œ๋‚˜๊ฐ€๋ฉด ๋˜๋Š” ๊ฒƒ์ด์—ˆ๋‹ค.
๋‚˜๋Š” ๊ฐ•์˜์—์„œ ๋“ค์—ˆ๋˜ ๋‚ด์šฉ๋“ค์„ ๊ธฐ์–ตํ•ด๋ณด๋ฉด์„œ ์ฝ”๋“œ๋ฅผ ์ฑ„์›Œ๋‚˜๊ฐ”๊ณ  ๋ฌด์‚ฌํžˆ ํŽ˜์ด์ง€๋ฅผ ์™„์„ฑํ•œ ํ›„ ๋ฐ์ดํ„ฐ๊ฐ€ ์ž˜ ๋ณด์—ฌ์ง€๋Š”์ง€ ํ…Œ์ŠคํŠธ๊นŒ์ง€ ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค ๐Ÿ˜Ž๐Ÿ˜Ž๐Ÿ˜Ž

$(".row-cols-3").empty();
const querySnapshot = await getDocs(collection(db, "foods"));

querySnapshot.forEach((doc) => {

    let title = doc.data().title;
    let comment = doc.data().comment;
    let star = "โญ".repeat(doc.data().star);
    let image = doc.data().image;

    // ๋ฌธ์„œ์˜ title, comment, image, star ํ•„๋“œ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”์ถœํ•œ ๋ณ€์ˆ˜๋ช…์„ ๊ฐ–๊ณ ,
    // tempHtml ๋ฌธ์ž์—ด์— ๊ฐ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•œ ์นด๋“œ์˜ HTML ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•˜์„ธ์š”.

    let tempHtml = `
    <div class="col">
        <div class="card h-100">
            <img src="${image}"
                class="card-img-top" alt="...">
            <div class="card-body">
                <h4 class="card-title">${title}</h4>
                <p class="card-text">${comment}</p>
                <p>${star}</p>
                <button class="card-button">์ฃผ๋ฌธํ•˜๊ธฐ</button>
            </div>
        </div>
    </div>`;

    $(".row-cols-3").append(tempHtml);
});

์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋“ค์ด ๋ชจ๋‘ ์ž˜ ๋ณด์ด๋Š” ๊ฒƒ์„ ํ™•์ธํ•œ ํ›„ ์ˆ™์ œ๋ฅผ ์ œ์ถœํ–ˆ๋‹ค ๐Ÿ˜ƒ๐Ÿ˜ƒ

 

+ ์˜ค๋Š˜ ์‹คํ–‰ํ•œ ๊ณ„ํš

  • SQL, ์ž๋ฐ” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ฐ๊ฐ 2๋ฌธ์ œ์”ฉ ํ’€์ด ๐Ÿ˜Ž
    • SQL ๋ฌธ์ œ๋“ค์€ ๋ชจ๋‘ ์ „์— ํ’€์–ด๋ดค๋˜ ๋ฌธ์ œ๋“ค์ด์—ฌ์„œ ์‰ฝ๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.
    • ์ž๋ฐ” ๋ฌธ์ œ๋“ค๋„ ๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•˜๋ฉด ์‰ฝ๊ฒŒ ํ•ด๊ฒฐ๋˜๋Š” ๋ฌธ์ œ์—ฌ์„œ ์–ด๋ ค์›€ ์—†์ด ํ•ด๊ฒฐํ–ˆ๋‹ค!
  • Java ์ž…๋ฌธ ๊ฐ•์˜_์Šค์ฝ”ํ”„, ํ˜•๋ณ€ํ™˜ ๊ฐ•์˜ ๋“ฃ๊ธฐ ๐Ÿ˜Ž
    • ์Šค์ฝ”ํ”„๋ผ๋Š” ๊ฐœ๋…์„ ์ด๋ฒˆ์— ์ฒ˜์Œ ์•Œ๊ฒŒ ๋˜์—ˆ๋Š”๋ฐ, ๊ฐ•์˜๋ฅผ ๋“ค์œผ๋ฉด์„œ ๋ธ”๋กœ๊ทธ์— ์ •๋ฆฌํ•˜๋‹ค ๋ณด๋‹ˆ ๊ฐœ๋…์„ ์™„๋ฒฝํ•˜๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด ๋ณ€์ˆ˜๊ฐ€ ์ƒ์กดํ•  ์ˆ˜ ์žˆ๋Š” ์˜์—ญ์„ ์˜๋ฏธํ–ˆ๋‹ค!
  • ์›น ๊ฐœ๋ฐœ ์ข…ํ•ฉ 5์ฃผ์ฐจ ๊ฐ•์˜ ๋“ฃ๊ธฐ ๐Ÿ˜Ž
    • ์›น ๊ฐœ๋ฐœ ํ›„ Github๋ฅผ ํ†ตํ•ด ๋ฐฐํฌํ•˜๋Š” ๊ณผ์ •๊นŒ์ง€ ์ง์ ‘ ์ง„ํ–‰ํ•˜๋ฉด์„œ ๋‚ด๊ฐ€ ๋งŒ๋“  ํŽ˜์ด์ง€์— ์ฃผ์†Œ๊นŒ์ง€ ๋ถ™๋Š” ๊ฑธ ํ™•์ธํ•˜๋‹ˆ๊นŒ ์‹ ๊ธฐํ–ˆ๋‹ค.... ๋‚ด๊ฐ€ ๋งŒ๋“  ํŽ˜์ด์ง€๊ฐ€ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค๋„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค๋‹ˆ ๐Ÿ˜ฎ๐Ÿ˜ฎ๐Ÿ˜ฎ ๊ฐ•์˜๋Š” ์ „๋ถ€ ๋“ค์—ˆ์ง€๋งŒ... ์ฃผ๋ง๋™์•ˆ ์•ˆ๋ณด๋ฉด ๊นŒ๋จน์„ ๊ฒŒ ๋ป”ํ•˜๋‹ˆ ๋ณต์Šต์„ ํ™•์‹คํ•˜๊ฒŒ ํ•ด๋‘ฌ์•ผ๊ฒ ๋‹ค.......