💻 JavaScript/기초 문법

Firebase / 데이터베이스

seheej 2024. 7. 16. 12:11

Firebase란?

: 구글이 개발한 모바일 및 웹 애플리케이션 개발 플랫폼 (클라우드 기반 NoSQL 데이터베이스)

  • 웹 서버를 대신 만들어주는 서비스
  • 서버 개발 없이 제작 가능
  • 백엔드 코드 한 줄 없이도 프론트지식(HTML, CSS, JS)만 알아도 웹 서비스 출시 가능!

 

데이터베이스란?

: 데이터를 저장하고 여러사람들이 관리하는 데이터 모음

  • 관계형 데이터 베이스
    • 테이블 형식으로 데이터를 저장하며, 각 테이블간의 관계를 통해 데이터를 연결
    • 주로 틀이 짜여져 있고 사람의 실수가 있어서는 안되는 곳에서 사용
  • 비관계형 데이터 베이스
    • 테이블 형식이 아닌 다양한 데이터 모델을 사용하여 데이터를 저장
    • 주로 앞으로 변경될 여지가 많은 데이터(스타트업), 대용량 고성능 처리에 적합

[addDoc] Firestore Database에 데이터 넣기

// 기본 코드스니펫
$("#id").click(async function () {
    let doc = {};
    await addDoc(collection(db, "콜렉션이름"), doc);
})

 

[getDocs] Firestore Database에서 데이터 가져오기

// 기본 코드스니펫
let docs = await getDocs(collection(db, "콜렉션이름"));
docs.forEach((doc) => {
    let row = doc.data();
    console.log(row);
});

Firebase 사용하기

  • firebase를 사용하려면 <script></script>를  <script type="module"></script>로 변경해 줌
  • 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";


// Firebase 구성 정보 설정
const firebaseConfig = {
	본인 설정 내용 채우기 
};


// Firebase 인스턴스 초기화
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);

 

  • 모듈로 변경하게 되면 script가 맨 마지막에 불러와짐 (onClick이 작동이 안되기 때문에 동적으로 만들어 줘야 함)

 

Firebase 사용 전

<!doctype html>
<html lang="en">

<head>
    <script>
        function openclose() {
            $('#postingbox').toggle();
        }
        function makeCard() {
            let image = $('#image').val();
            let title = $('#title').val();
            let content = $('#content').val();
            let date = $('#date').val();

            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">${content}</p>
                    </div>
                    <div class="card-footer">
                        <small class="text-muted">${date}</small>
                    </div>
                </div>
            </div>`;
            $('#card').append(temp_html);
        }
    </script>
</head>

<body>
    <div class="mytitle">
        <h1>나만의 추억 앨범</h1>
        <button onclick="openclose()">추억 저장하기</button>
    </div>
    <div class="mypostingbox" id="postingbox">
        <div class="form-floating mb-3">
            <input type="email" class="form-control" id="image" placeholder="name@example.com">
            <label for="floatingInput">앨범 이미지</label>
        </div>
        <div class="form-floating mb-3">
            <input type="email" class="form-control" id="title" placeholder="name@example.com">
            <label for="floatingInput">앨범 제목</label>
        </div>
        <div class="form-floating">
            <input type="email" class="form-control" id="content" placeholder="name@example.com">
            <label for="floatingTextarea">앨범 내용</label>
        </div>
        <div class="form-floating mb-3">
            <input type="email" class="form-control" id="date" placeholder="name@example.com">
            <label for="floatingInput">앨범 날짜</label>
        </div>
        <div class="mybtn">
            <button onclick="makeCard()" type="button" class="btn btn-dark">기록하기</button>
            <button type="button" class="btn btn-outline-dark">닫기</button>
        </div>
    </div>

    <div class="mycards">
        <div id="card" class="row row-cols-1 row-cols-md-4 g-4">
            <div class="col">
                <div class="card h-100">
                    <img src="https://images.unsplash.com/photo-1446768500601-ac47e5ec3719?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1446&q=80"
                        class="card-img-top" alt="...">
                    <div class="card-body">
                        <h5 class="card-title">앨범 제목</h5>
                        <p class="card-text">앨범 내용</p>
                    </div>
                    <div class="card-footer">
                        <small class="text-muted">앨범 날짜</small>
                    </div>
                </div>
            </div>
        </div>
    </div>


</body>

</html>

 

 

Firebase 사용 후

makeCard()함수 수정 전

function makeCard() {
    let image = $('#image').val();
    let title = $('#title').val();
    let content = $('#content').val();
    let date = $('#date').val();

    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">${content}</p>
            </div>
            <div class="card-footer">
                <small class="text-muted">${date}</small>
            </div>
        </div>
    </div>`;
    $('#card').append(temp_html);
}
    1. body안의 기록하기 버튼의 onClick을 제거하고, script안의 makeCard() function을 삭제함
    2. body안의 기록하기 버튼에 postingbtn id값 생성 후, script안에 $("#postingbtn").click(async function () { })코드 생성
    3. 기존의 makeCard() function안에 있던 코드들을 조금 전에 생성한 $("#postingbtn").click(async function () { }) 안에 붙여 넣는다.
    4. 데이터 추가 스켈레톤을 기존 데이터에 맞게 수정

makeCard()함수 수정 후

$("#postingbtn").click(async function () {
    let image = $('#image').val();
    let title = $('#title').val();
    let content = $('#content').val();
    let date = $('#date').val();

    let doc = {
        'image': image,
        'title': title,
        'content': content,
        'date': date,
    };
    await addDoc(collection(db, "albums"), doc);
    alert('Saved!')
    window.location.reload(); // 새로고침
})

 onclick기능 firebase 사용 전

function openclose() {
    $('#postingbox').toggle();
}
        
<button onclick="openclose()">추억 저장하기</button>

 

onclick기능 firebase 사용 후

$("#savebtn").click(async function () {
            $('#postingbox').toggle(); // postingbox 열고 닫기
        })
        
<button id="savebtn">추억 저장하기</button>

 

document ready를 이용한 fetch코드 firebase 사용 전

$(document).ready(function () {
    let url = "http://spartacodingclub.shop/sparta_api/seoulair";
    fetch(url)
        .then(res => res.json())
        .then(data => {
            let airquality = data['RealtimeCityAir']['row'][0]['IDEX_NM']
            $('#airquality').text(airquality)
        })
})

 

fetch코드 firebase 사용 후

let url = "http://spartacodingclub.shop/sparta_api/seoulair";

fetch(url)
    .then(res => res.json())
    .then(data => {
        let airquality = data['RealtimeCityAir']['row'][0]['IDEX_NM'];
        $('#airquality').text(airquality);

    })

 


 

데이터 넣고 카드 생성하는 함수 firebase 사용 전

function makeCard() {
    let image = $('#image').val();
    let title = $('#title').val();
    let content = $('#content').val();
    let date = $('#date').val();

    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">${content}</p>
            </div>
            <div class="card-footer">
                <small class="text-muted">${date}</small>
            </div>
        </div>
    </div>`;
    $('#card').append(temp_html);
}

 

데이터 넣고 카드 생성하는 함수 firebase 사용 후

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

    let image = row['image'];
    let title = row['title'];
    let content = row['content'];
    let date = row['date'];

    let temp_html = `
    <div class="col">
        <div class="card h-100">
            <img src="${image}"
                class="card-img-top" alt="poster image">
            <div class="card-body">
                <h5 class="card-title">${title}</h5>
                <p class="card-text">${content}</p>
            </div>
            <div class="card-footer">
                <small class="text-body-secondary">${date}</small>
            </div>
        </div>
    </div>`;

    $('#card').append(temp_html);
});

화면 새로고침 함수

window.location.reload() // 화면 새로고침 하기

 


 

완성 코드

<!doctype html>
<html lang="en">

<head>
    <script type="module">
        // 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: "AIzaSyCz-aTF0iQvQilKJyrTHQxg1T2X_13trtw",
            authDomain: "sparta-49ce5.firebaseapp.com",
            projectId: "sparta-49ce5",
            storageBucket: "sparta-49ce5.appspot.com",
            messagingSenderId: "819019173056",
            appId: "1:819019173056:web:e47a0781c0b38268923125",
            measurementId: "G-0NFWX91DD1"
        };

        // Firebase 인스턴스 초기화
        const app = initializeApp(firebaseConfig);
        const db = getFirestore(app);

        $("#postingbtn").click(async function () {
            let image = $('#image').val();
            let title = $('#title').val();
            let content = $('#content').val();
            let date = $('#date').val();

            let doc = {
                'image': image,
                'title': title,
                'content': content,
                'date': date
            };
            await addDoc(collection(db, "albums"), doc);
            alert('저장완료!');
            window.location.reload();
        })

        $("#savebtn").click(async function () {
            $('#postingbox').toggle();
        })


        let url = "http://spartacodingclub.shop/sparta_api/seoulair";
        fetch(url).then(res => res.json()).then(data => {
            let mise = data['RealtimeCityAir']['row'][0]['IDEX_NM']
            $('#msg').text(mise)
        })

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

            let image = row['image'];
            let title = row['title'];
            let content = row['content'];
            let date = row['date'];

            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">${content}</p>
                    </div>
                    <div class="card-footer">
                        <small class="text-muted">${date}</small>
                    </div>
                </div>
            </div>`;
            $('#card').append(temp_html);
        });

    </script>
</head>

<body>
    <div class="mytitle">
        <h1>나만의 추억 앨범</h1>
        <p>현재 서울의 미세먼지 : <span id="msg">나쁨</span></p>
        <button id="savebtn">추억 저장하기</button>
    </div>
    <div class="mypostingbox" id="postingbox">
        <div class="form-floating mb-3">
            <input type="email" class="form-control" id="image" placeholder="name@example.com">
            <label for="floatingInput">앨범 이미지</label>
        </div>
        <div class="form-floating mb-3">
            <input type="email" class="form-control" id="title" placeholder="name@example.com">
            <label for="floatingInput">앨범 제목</label>
        </div>
        <div class="form-floating">
            <input type="email" class="form-control" id="content" placeholder="name@example.com">
            <label for="floatingTextarea">앨범 내용</label>
        </div>
        <div class="form-floating mb-3">
            <input type="email" class="form-control" id="date" placeholder="name@example.com">
            <label for="floatingInput">앨범 날짜</label>
        </div>
        <div class="mybtn">
            <button id="postingbtn" type="button" class="btn btn-dark">기록하기</button>
            <button type="button" class="btn btn-outline-dark">닫기</button>
        </div>
    </div>

    <div class="mycards">
        <div id="card" class="row row-cols-1 row-cols-md-4 g-4">
            <div class="col">
                <div class="card h-100">
                    <img src="https://images.unsplash.com/photo-1446768500601-ac47e5ec3719?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1446&q=80"
                        class="card-img-top" alt="...">
                    <div class="card-body">
                        <h5 class="card-title">앨범 제목</h5>
                        <p class="card-text">앨범 내용</p>
                    </div>
                    <div class="card-footer">
                        <small class="text-muted">앨범 날짜</small>
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
</html>