본문 바로가기
내일배움캠프_게임서버(202410)/완강 - [왕초보] 웹개발 종합반

[왕초보] 웹개발 4주차 : 파이어베이스와 파이어스토어

by GREEN나무 2024. 10. 28.
728x90

◆ 파이어 베이스

파이어베이스  웹 앱 추가

Firebase SDK 추가

<script> 테그

더보기
<script type="module">
  // Import the functions you need from the SDKs you need
  import { initializeApp } from "https://www.gstatic.com/firebasejs/11.0.1/firebase-app.js";
  import { getAnalytics } from "https://www.gstatic.com/firebasejs/11.0.1/firebase-analytics.js";
  // TODO: Add SDKs for Firebase products that you want to use
  // https://firebase.google.com/docs/web/setup#available-libraries

  // Your web app's Firebase configuration
  // For Firebase JS SDK v7.20.0 and later, measurementId is optional
  const firebaseConfig = {
    apiKey: "AIzaSyARvXqt1jk70WhUPCZ1yCDxqK4V0gsZ-uc",
    authDomain: "sqarta-5fffb.firebaseapp.com",
    projectId: "sqarta-5fffb",
    storageBucket: "sqarta-5fffb.appspot.com",
    messagingSenderId: "786388961610",
    appId: "1:786388961610:web:36b035fbf79f0391c759b3",
    measurementId: "G-X895B7R0TW"
  };

  // Initialize Firebase
  const app = initializeApp(firebaseConfig);
  const analytics = getAnalytics(app);
</script>

 

데이터베이스를 사용하면 정보를 쉽게 찾고 업데이트할 수 있고, 많은 양의 정보를 효율적으로 관리할 수 있습니다.

DB의 종류

1) 관계형 DB

    SQL   (엑셀 같은 )

    정리된 정보를 다룰 때 사용합니다.

    ex) 은행, 대기업

2) 비관계형 DB

    NoSQL

    복잡하거나 유연한 정보를 다룰 때 사용합니다.

    ex) 스타트업

 

파이어스토어

파이어스토어 (Firestore)는 구글의 클라우드 기반 NoSQL 데이터베이스입니다

 

사용 준비하기

시작 전 album 파일

더보기
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>나만의 추억앨범</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <style>
        @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100..900&family=Nunito:ital,wght@0,200..1000;1,200..1000&display=swap');

        * {
            font-family: "Noto Sans KR", sans-serif;
        }

        .mytitle {
            height: 250px;
            background-color: green;
            color: white;

            /*박스안에 있는 내용물 정렬하기 (4줄)*/

            /*해당 요소를 Flexbox 컨테이너로 지정합니다.*/
            display: flex;

            /*Flexbox의 기본 방향을 세로로 설정합니다. 내부의 아이템 수직으로 배열됩니다.*/
            flex-direction: column;

            /*수평축에서 중앙으로 정렬합니다.(좌우에서 중앙)*/
            align-items: center;

            /*수직축에서 중앙으로 정렬합니다.(상하에서 중앙)*/
            justify-content: center;

            /*그림 삽입(3줄 기억하기)*/
            background-image: url('https://images.unsplash.com/photo-1511992243105-2992b3fd0410?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80');
            background-position: center;
            background-size: cover;
        }

        .mytitle>button {
            width: 150px;
            height: 50px;

            /*투명한 바탕*/
            background-color: transparent;
            color: white;

            /*버튼 테두리에 1px만큼 흰색으로 채웁니다.*/
            border: 1px solid white;
            border-radius: 5px;
            margin-top: 20px;
        }

        .mycard {
            /*background-color: green;*/
            width: 1220px;
            margin: 30px auto 0px auto;
        }

        .mypostingbox {
            width: 500px;
            margin: 30px auto 0px auto;
            padding: 20px;

            /*그림자*/
            /*box-shadow: 우측그림자크기 아래 전체연하게 전체진하게;*/
            box-shadow: 0px 0px 3px 0px;
            border-radius: 5px;

        }

        .mybtn {

            /*중앙배열*/
            display: flex;
            flex-direction: row;
            /*가로배열*/
            align-items: center;
            justify-content: center;
        }

        .mybtn>button {
            margin-right: 5px;
        }
    </style>
    <script>
        $(document).ready(function () { // 페이지 로딩되면 자동으로 Fetch를 합니다.
            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)
            })
        })

        // Post Box 버튼으로 여닫기
        function openclose() {
            $('#postingbox').toggle();
        }

        function makeCard() {
            // 특정한 곳에 있는 벨류값 가져오기
            let image = $('#image').val();
            let title = $('#title').val();
            let content = $('#content').val();
            let date = $('#date').val();

            // 뭔가를 만들어서 붙이는 <p>키 기능
            // let temp_html = `<p>카드 하나 <div> </p>`;
            let new_card = `
            <div class="card">
                <img src="${image}"
                    class="card-img-top" alt="...">
                <div class="card-body">
                    <h5 class="card-title">${title}</h5>
                    <p class="card-text">${content}</p>
                    <p class="card-text"><small class="text-body-secondary">${date}</small></p>
                </div>
            </div>`;

            $('#card').append(new_card);
        }
    </script>
</head>

<body>
    <div class="mytitle">
        <h1>나만의 추억앨범</h1>
        <p>현재 서울의 미세먼지 : <span id="msg">날씨</span></p>
        <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="앨범 이미지">
            <label for="floatingInput">앨범 이미지</label>
        </div>

        <div class="form-floating mb-3">
            <input type="email" class="form-control" id="title" placeholder="앨범 제목">
            <label for="floatingInput">앨범 제목</label>
        </div>
        <div class="form-floating mb-3">
            <input type="email" class="form-control" id="content" placeholder="앨범 내용">
            <label for="floatingInput">앨범 내용</label>
        </div>
        <div class="form-floating mb-3">
            <input type="email" class="form-control" id="date" placeholder="앨범 날짜">
            <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="mycard">
        <!--부트스트랩에서 가져온 카드 코드-->
        <!-- <div class="card-group"> -->
        <!-- id 지정, 큰 화면에서 한 줄에 4개씩 배치 -->
        <div id="card" class="row row-cols-1 row-cols-md-4 g-4">
            <div class="card">
                <!--이미지 URL-->
                <img src="https://images.unsplash.com/photo-1511992243105-2992b3fd0410?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80"
                    class="card-img-top" alt="...">
                <div class="card-body">
                    <h5 class="card-title">앨범 제목</h5>
                    <p class="card-text">엘범 내용</p>
                    <p class="card-text"><small class="text-body-secondary">앨범 날짜</small></p>
                </div>
            </div>
            <div class="card">
                <!--이미지 URL-->
                <img src="https://images.unsplash.com/photo-1511992243105-2992b3fd0410?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80"
                    class="card-img-top" alt="...">
                <div class="card-body">
                    <h5 class="card-title">앨범 제목</h5>
                    <p class="card-text">엘범 내용</p>
                    <p class="card-text"><small class="text-body-secondary">앨범 날짜</small></p>
                </div>
            </div>
            <div class="card">
                <!--이미지 URL-->
                <img src="https://images.unsplash.com/photo-1511992243105-2992b3fd0410?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80"
                    class="card-img-top" alt="...">
                <div class="card-body">
                    <h5 class="card-title">앨범 제목</h5>
                    <p class="card-text">엘범 내용</p>
                    <p class="card-text"><small class="text-body-secondary">앨범 날짜</small></p>
                </div>
            </div>
            <div class="card">
                <!--이미지 URL-->
                <img src="https://images.unsplash.com/photo-1511992243105-2992b3fd0410?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80"
                    class="card-img-top" alt="...">
                <div class="card-body">
                    <h5 class="card-title">앨범 제목</h5>
                    <p class="card-text">엘범 내용</p>
                    <p class="card-text"><small class="text-body-secondary">앨범 날짜</small></p>
                </div>
            </div>
        </div>

    </div>
</body>

</html>

 

스크립트 타입을 모듈로 하고 Firebase SDK 라이브러리를 가져오세요

    <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";

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

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

 

 

파이어베이스 구성정보 설정을 지우고

프로젝트 설정 > SDK 설정 및 구성 > 구성 > 앱의 키 및 식별자가 포함된 Firebase 구성 객체 코드를 가져옵니다.

<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";


        // Firebase 구성 정보 설정 -> 프로젝트 설정의 SDK 설정 및 구성 가져오기
        // For Firebase JS SDK v7.20.0 and later, measurementId is optional
        const firebaseConfig = {
            apiKey: "AIzaSyARvXqt1jk70WhUPCZ1yCDxqK4V0gsZ-uc",
            authDomain: "sqarta-5fffb.firebaseapp.com",
            projectId: "sqarta-5fffb",
            storageBucket: "sqarta-5fffb.appspot.com",
            messagingSenderId: "786388961610",
            appId: "1:786388961610:web:36b035fbf79f0391c759b3",
            measurementId: "G-X895B7R0TW"
        };


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

 

 

 

버튼으로 data 저장

<script>        // 어떤 'id'값에 click을 담은 것
        // 모듈을 쓰면 'onclick'이 잘 안되서 아래를 사용합니다.
        //         $("#id").click(async function () {
        //     let doc = {}; // doc는 담을 것
        //     await addDoc(collection(db, "콜렉션이름"), doc);  // 이 줄이 핵심
        // })

        $("#posting_btn").click(async function () {
            let doc = { 'name': 'bob', 'age': 30 };
            await addDoc(collection(db, "albums"), doc);
        })

        $("#openclos_btn").click(async function () {
            $('#postingbox').toggle();
        })
</script>        
        ...
         <!-- onclick 대신 id를 지정합니다 -->
        <button id="openclos_btn">추억 저장하기</button>
    </div>...         
            <button id='posting_btn' type="button" class="btn btn-dark">기록하기</button>

 

<script>
            $("#posting_btn").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);            
        })
...

 

새로고침

<script>
    window.location.reload(); // 새로고침

 

파이어베이스의 데이터 삭제

 

스크립트 타입을 모듈로 바꾸면 let이 가장 나중에(로딩 끝나고) 실행됩니다.

// 스크립트 타입을 모듈(파이어베이스 사옹 시 필요)이라고 적으면 이 스크립트가 가장 나중에 호줄됩니다.
        // $(document).ready(function () {}) 필요 없음
        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 변수명 = row['#키이름']; 키값을 변수에 넣음
            let title = row['title'];
            let content = row['content'];
            let date = row['date'];

            // 뭔가를 만들어서 붙이는 <p>키 기능
            // let temp_html = `<p>카드 하나 <div> </p>`;
            let temp_html = `
            <div class="card">
                <img src="${image}"
                    class="card-img-top" alt="...">
                <div class="card-body">
                    <h5 class="card-title">${title}</h5>
                    <p class="card-text">${content}</p>
                    <p class="card-text"><small class="text-body-secondary">${date}</small></p>
                </div>
            </div>`;
            $('#card').append(temp_html);
        });

 

파이어배이스

 

앨범 전체 코드

더보기
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>나만의 추억앨범</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <style>
        @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100..900&family=Nunito:ital,wght@0,200..1000;1,200..1000&display=swap');

        * {
            font-family: "Noto Sans KR", sans-serif;
        }

        .mytitle {
            height: 250px;
            background-color: green;
            color: white;

            /*박스안에 있는 내용물 정렬하기 (4줄)*/

            /*해당 요소를 Flexbox 컨테이너로 지정합니다.*/
            display: flex;

            /*Flexbox의 기본 방향을 세로로 설정합니다. 내부의 아이템 수직으로 배열됩니다.*/
            flex-direction: column;

            /*수평축에서 중앙으로 정렬합니다.(좌우에서 중앙)*/
            align-items: center;

            /*수직축에서 중앙으로 정렬합니다.(상하에서 중앙)*/
            justify-content: center;

            /*그림 삽입(3줄 기억하기)*/
            background-image: url('https://images.unsplash.com/photo-1511992243105-2992b3fd0410?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80');
            background-position: center;
            background-size: cover;
        }

        .mytitle>button {
            width: 150px;
            height: 50px;

            /*투명한 바탕*/
            background-color: transparent;
            color: white;

            /*버튼 테두리에 1px만큼 흰색으로 채웁니다.*/
            border: 1px solid white;
            border-radius: 5px;
            margin-top: 20px;
        }

        .mycard {
            /*background-color: green;*/
            width: 1220px;
            margin: 30px auto 0px auto;
        }

        .mypostingbox {
            width: 500px;
            margin: 30px auto 0px auto;
            padding: 20px;

            /*그림자*/
            /*box-shadow: 우측그림자크기 아래 전체연하게 전체진하게;*/
            box-shadow: 0px 0px 3px 0px;
            border-radius: 5px;

        }

        .mybtn {

            /*중앙배열*/
            display: flex;
            flex-direction: row;
            /*가로배열*/
            align-items: center;
            justify-content: center;
        }

        .mybtn>button {
            margin-right: 5px;
        }
    </style>
    <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";


        // Firebase 구성 정보 설정 -> 프로젝트 설정의 SDK 설정 및 구성 가져오기
        /*const firebaseConfig = {
            // 본인 설정 내용 채우기 
        }; */
        // For Firebase JS SDK v7.20.0 and later, measurementId is optional
        const firebaseConfig = {
            apiKey: "AIzaSyARvXqt1jk70WhUPCZ1yCDxqK4V0gsZ-uc",
            authDomain: "sqarta-5fffb.firebaseapp.com",
            projectId: "sqarta-5fffb",
            storageBucket: "sqarta-5fffb.appspot.com",
            messagingSenderId: "786388961610",
            appId: "1:786388961610:web:36b035fbf79f0391c759b3",
            measurementId: "G-X895B7R0TW"
        };


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



        // 어떤 'id'값에 click을 담은 것
        // 모듈을 쓰면 'onclick'이 잘 안되서 아래를 사용합니다.
        //         $("#id").click(async function () {
        //     let doc = {}; // doc는 담을 것
        //     await addDoc(collection(db, "콜렉션이름"), doc);  // 이 줄이 핵심
        // })

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

            let doc = {
                'image': image,
                'title': title,
                'coment': coment,
                'date': date
            };
            await addDoc(collection(db, "albums"), doc);
            alert('저장 완료')
            window.location.reload(); // 새로고침        
        })

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





        // 스크립트 타입을 모듈(파이어베이스 사옹 시 필요)이라고 적으면 이 스크립트가 가장 나중에 호줄됨
        // $(document).ready(function () {}) 필요 없음
        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 변수명 = row['#키이름']; 키값을 변수에 넣음
            let title = row['title'];
            let coment = row['coment'];
            let date = row['date'];

            // 뭔가를 만들어서 붙이는 <p>키 기능
            // let temp_html = `<p>카드 하나 <div> </p>`;
            let temp_html = `
            <div class="card">
                <img src="${image}"
                    class="card-img-top" alt="...">
                <div class="card-body">
                    <h5 class="card-title">${title}</h5>
                    <p class="card-text">${coment}</p>
                    <p class="card-text"><small class="text-body-secondary">${date}</small></p>
                </div>
            </div>`;

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



    </script>
</head>

<body>
    <div class="mytitle">
        <h1>나만의 추억앨범</h1>
        <p>현재 서울의 미세먼지 : <span id="msg">날씨</span></p>
        <button id="openclos_btn">추억 저장하기</button>
    </div>

    <div class="mypostingbox" id="postingbox">
        <div class="form-floating mb-3">
            <input type="email" class="form-control" id="image" placeholder="앨범 이미지">
            <label for="floatingInput">앨범 이미지</label>
        </div>

        <div class="form-floating mb-3">
            <input type="email" class="form-control" id="title" placeholder="앨범 제목">
            <label for="floatingInput">앨범 제목</label>
        </div>
        <div class="form-floating mb-3">
            <input type="email" class="form-control" id="coment" placeholder="앨범 내용">
            <label for="floatingInput">앨범 내용</label>
        </div>
        <div class="form-floating mb-3">
            <input type="email" class="form-control" id="date" placeholder="앨범 날짜">
            <label for="floatingInput">앨범 날짜</label>
        </div>
        <div class="mybtn">
            <!-- onclick 대신 id 지정 -->
            <button id='posting_btn' type="button" class="btn btn-dark">기록하기</button>
            <button id='clos_btn' type="button" class="btn btn-outline-dark">닫기</button>
        </div>
    </div>

    <div class="mycard">
        <!--부트스트랩에서 가져온 카드 코드-->
        <!-- <div class="card-group"> -->
        <!-- id 지정, 큰 화면에서 한 줄에 4개씩 배치 -->
        <div id="card" class="row row-cols-1 row-cols-md-4 g-4">
            <!-- 
            <div class="card">
                <img src="https://images.unsplash.com/photo-1511992243105-2992b3fd0410?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80"
                    class="card-img-top" alt="...">
                <div class="card-body">
                    <h5 class="card-title">앨범 제목</h5>
                    <p class="card-text">엘범 내용</p>
                    <p class="card-text"><small class="text-body-secondary">앨범 날짜</small></p>
                </div>
            </div>
            -->
        
        </div>

    </div>
</body>

</html>

 

 

 

 

 

※ 요약

◆파이어베이스와 파이어스토어

◆데이터 저장하기 가져오기