본문 바로가기
내일배움캠프_게임서버(202410)/TIL,WIL

카드모달 만들면서 막히는 부분

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

파이어베이스 수정, 삭제하는 방법을 연구중입니다.

어째 잘 안되네요 ㅠㅠ

 

 

 

24.10.31 현황

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/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>
        .allcard {
            width: 1400px;
            display: flex;
            justify-content: center;
            margin: 30px auto 0px auto;

        }

        .myteamcard {
            height: auto;
            width: auto;
            padding: 15px;
            border: 1px solid black;
            border-radius: 5px;
            background-color: whitesmoke;
            margin: 24px 10px 0px 10px;
            display: flex;
            flex-direction: column;
            align-items: center;
        }

        .myteamcard:hover {
            background-color: rgba(0, 0, 0, 0.1);
            cursor: pointer;
        }


        /*faceimge 랑 cardtext를 묶는 거.*/

        .faceimge {
            display: flex;
            flex-direction: row;
            align-items: center;
            justify-content: center;
            border: 1px solid black;
            width: 175px;
            height: 225px;
            border-radius: 5px;
        }

        /*사진임*/

        .cardtext {
            margin: 0px 0px 0px 20px;
            padding: 15px;
            border: 1px solid black;
            border-radius: 5px;
            text-align: center;
            background-color: white;
        }

        /*이름,mbti등*/

        .cardtext2 {
            margin-top: 20px;
            padding: 15px;
            border: 1px solid black;
            border-radius: 5px;
            width: 287px;
            background-color: white;
        }

        /*장점등*/

        .blog-link {
            display: flex;
            justify-content: center;
            text-decoration: none;
            color: black;
            font-weight: bold;
        }


        .plsbt {
            height: 500px;
            width: 320px;
            border-radius: 5px;
        }

        .plsbt:hover {
            background-color: rgba(0, 0, 0, 0.1);
            /* 약간 어두워짐 */
            cursor: pointer;
        }

        .postingbtng {
            height: 500px;
            width: 330px;
        }

        /*위에 버튼 공간 잡는거 없으면 찌그러짐*/

        /*이 밑은 카드 누르면 나오는 팝업창이므로 바꾸기.*/
        .popup-overlay {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.5);
            display: none;
            justify-content: center;
            align-items: center;

        }

        .popup-content {
            padding: 20px;
            border-radius: 8px;
            text-align: center; 
            /*box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);*/
            background-color: rgb(108, 209, 162);
            width: 1000px;
            height: 600px;
            /* margin: 30px; */
            box-shadow: 0px 0px 30px 0px rgb(88, 163, 128);
        }

        .close-btn {
            margin-top: 10px;
            padding: 8px 16px;
            background-color: blue;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        #imgsbox {
            padding: 5px;
            margin-right: 15px;
            border-radius: 30px;
        }

        #infobox {
            padding: 5px;
            margin-left: 30px;
            border-radius: 30px;
            background-color: white;
        }

        #memberImg {
            width: 300px;
            height: 400px;
        }

        #link_img {
            width: 100px;
            height: 100px;
        }

        #blBtn {
            margin: 10px 10px 0px 10px;
            padding: 1px;
        }

        #infoup {
            margin: 10px 10px 0px 5px;
            border-radius: 10px;
            height: 160px;
        }

        #infodown {
            margin: 10px 10px 0px 5px;
            border-radius: 10px;
            height: 300px;
        }

        #info1 {
            height: max-content;
        }

        #info2 {
            background-color: rgba(108, 209, 162, 0.41);
            border-radius: 10px;
            height: 160px;
            text-align: left;
        }

        #reviseBtn {
            width: 90px;
            margin: 10px;
            padding: 3px;
        }

        #deleteBtn {
            width: 90px;
            margin: 10px;
            padding: 3px;
        }

        #info3 {
            height: 300px;
            background-color: rgba(108, 209, 162, 0.41);
            border-radius: 10px;
            text-align: left;
        }
    </style>


    <script type="module">

        // Firebase SDK 라이브러리 가져오기
        import { initializeApp } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-app.js";
        import { getFirestore, collection, addDoc, getDocs, deleteDoc, doc } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-firestore.js";
        //        import { getFirestore, doc, deleteDoc } from "https://www.gstatic.com/firebasejs/9.x/firebase-firestore.js";
        //
        import { getStorage, ref, uploadBytes, getDownloadURL } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-storage.js";


        // Firebase 구성 정보 설정
        const firebaseConfig = {
            apiKey: "AIzaSyCGqR4KmttjxTiDXOgnAlq_zK85FfceU_4",
            authDomain: "sparta-1aa54.firebaseapp.com",
            projectId: "sparta-1aa54",
            storageBucket: "sparta-1aa54.appspot.com",
            messagingSenderId: "210610766907",
            appId: "1:210610766907:web:f3553a0bb7e166be9c081e",
            measurementId: "G-8ETLMBCMF2"
        };

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


        let docs = await getDocs(collection(db, "members"));
        docs.forEach((doc) => {
            let row = doc.data();
            let imageUrl = row['imageUrl'];
            let name = row['name'];
            let mbti = row['mbti'];
            let hobby = row['hobby'];
            let introduction = row['introduction'];
            let strengths = row['strengths'];
            let collaborationStyle = row['collaborationStyle'];
            let resolution = row['resolution'];
            let blogLink = row['blogLink'];

            let temp_html = `        
       <div class="myteamcard">
            <div class="card">
                <img src="${imageUrl}"
                    class="faceimge">
                ardtext">
                    <div class="cardtext">
                        <h5 class="card-title">이름<p>${name}</p>
                        </h5>
        </div></div></div>`;
            let cardElement = $(temp_html).insertBefore('#cardlist');

            // 클릭 이벤트 핸들러 추가
            cardElement.click(function () {
                // $('#popup-name').text(name);  // 클릭한 카드의 이름을 팝업에 설정
                let temp_html = ` 
             <div>
    <div class="row">
        <div id="imgsbox" class="col-3">
            <div class="imgcard">
                <img id="memberImg" src="${imageUrl}" class="card-img-top" alt="...">
                <div>
                    <div class="row">

                        <!--블로그버튼-->
                        <button id="blBtn" type="button" class="col btn btn-outline-success">
                            <a href="${blogLink}" target="_blank" rel="noopener noreferrer">
                                <img id="link_img"
                                    src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTq_V5ImHw0BTMnCJ4GSqBsDdD-bxLsyuCh4Q5V7XX2aiVuxCbTG6RT2151CA1-G6XaE7k&usqp=CAU"
                                    class="card-img-top" alt="...">
                            </a>
                        </button>
                    </div>
                </div>
            </div>
        </div>
        <div class="col"></div>
        <div id="infobox" class="col-8">
            <div id="infoup" class="row">
                <div id="info1" class="col-3">
                    <table class="table">
                        <thead>
                            <tr>
                                <th scope="col">이름</th>
                                <th scope="col">${name}</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                                <th scope="row">MBTI</th>
                                <td>${mbti}</td>
                            </tr>
                            <tr>
                                <th scope="row">취미</th>
                                <td>${hobby}</td>
                            </tr>
                        </tbody>
                    </table>
                </div>
                <div id="info2" class="col-5">
                    <ul class=" list-group">
                        <p>${introduction}</p>
                    </ul>
                </div>
                <div class="col">
                    <button id="reviseBtn" type="button" class="btn btn-outline-secondary">
                        <a href="/.addcard.html" class="text-muted">수정</a>
                    </button>

                    <!--
                    <button id="reviseBtn" type="button" class="btn btn-outline-secondary">
    <a class="p-2 text-muted" href="/._includes\addcard.html">수정</a></button>-->
                    <button id="deleteBtn" type="button" class="btn btn-outline-secondary">삭제</button>
                </div>
            </div>
            <div id="infodown" class="row">
                <div id="info3" class="col-8">
                    <ul class=" list-group">
                        <p id="strengths" style="display: none;">${strengths}</p>
                        <p id="collaborationStyle" style="display: none;">${collaborationStyle}</p>
                        <p id="resolution" style="display: none;">${resolution}</p>
                    </ul>
                </div>
                <div class="col-2">
                    <div class="btn-group-vertical" role="group" aria-label="Vertical radio toggle button group">
                        <input type="radio" class="btn-check" name="vbtn-radio" id="vbtn-radio1" autocomplete="off"
                            checked>
                        <label id="strengthsBtn" class="btn btn-outline-danger" for="vbtn-radio1">장점</label>
                        <input type="radio" class="btn-check" name="vbtn-radio" id="vbtn-radio2" autocomplete="off">
                        <label id="resolutionBtn" class="btn btn-outline-danger" for="vbtn-radio2">각오</label>
                        <input type="radio" class="btn-check" name="vbtn-radio" id="vbtn-radio3" autocomplete="off">
                        <label id="collaborationStyleBtn" class="btn btn-outline-danger" for="vbtn-radio3">협업스타일</label>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div> `
                

// 전역 변수로 PopCardElement 선언
let PopCardElement = $(temp_html).insertBefore('#popup_content');





//let PopCardElement = $(temp_html).insertBefore('#popup_content');
                
                $('#popup').css('display', 'flex');  // 팝업 열기
                $("#strengths").show();
                $("#collaborationStyle").hide();
                $("#resolution").hide();
                console.log('팝업 열림');
            })
        });
        
        // 수정화면으로 이동
        $("#reviseBtn").click(function () {            
            $("#popup").css("display", "none");
            console.log('수정화면으로 이동')

        })

        // 파이어베이스에서 해당 자료 삭제
$("#deleteBtn").click(async function (e) {

    // e.preventDefault();

    $("#popup").css("display", "none");
    //if (name === `${name}`) {
        //if (confirm("정말 삭제 하시겠습니까?")) {
        //const docRef = doc(db, 'members', `${name}`);
        //await deleteDoc(docRef);
        console.log('삭제되었습니다.');
        //    window.location.href = './membercard.html';
        //} else {
        //    return false;
        
    //}
});

        // 텍스트 -> 버튼으로 토글 사용하기
        $("#strengthsBtn").click(function () { // 장점
            $("#strengths").show();
            $("#collaborationStyle").hide();
            $("#resolution").hide();
        });

        $("#collaborationStyleBtn").click(function () { // 협업 스타일
            $("#strengths").hide();
            $("#collaborationStyle").show();
            $("#resolution").hide();
        });

        $("#resolutionBtn").click(function () { // 각오
            $("#strengths").hide();
            $("#collaborationStyle").hide();
            $("#resolution").show();
        });


        // 팝업 닫기 버튼 클릭 시 팝업을 닫습니다.
        $("#clbtn").click(function () {
            // PopCardElement.remove();
            if (PopCardElement) {
    PopCardElement.remove();
}

            $("#popup_content").empty();
             $("#popup").css("display", "none");
            

        });

        $(document).ready(function () {
            $("#plsbtn").click(function () {
                window.location.href = 'addcard.html';
            });
        });
        //분리 안하면 작동을 안함;;
    </script>
    <script></script>
</head>

<body>
    <div class="allcard">
        <div class="row row-cols-1 row-cols-md-3 g-4">
            <div class="postingbtng" id="cardlist">

            </div>
        </div>

    </div>


<!-- 팜업창 -->
    <div class="popup-overlay" id="popup">
        <div class="popup-content">
            <!-- <h4>팝업 창</h4>
            <p>이름: <span id="popup-name"></span></p> -->
        <div id="popup_content">
           
            <button class="close-btn" id="clbtn">닫기</button>
        </div></div>
    </div>




</body>


</html>

> 오류1

팝업창을 닫은 뒤 멤버카드를 눌러 다시 팝업창이 뜰 때 이전 팝업창의 내용이 남아있습니다.

 

      수정 완료

<button class="close-btn" id="clbtn">닫기</button>
        // 팝업 닫기 버튼 클릭 시 팝업을 닫습니다.        
        $("#clbtn").click(function () {
            document.getElementById("removePop").remove();
            $("#popup").css("display", "none");
            console.log(' $("#popup").css("display", "none");')
        })

 

> 오류2

수정, 삭제버튼 오류

삭제버튼 해결함

where빼고 다시 시도해서 성공함

$(document).on("click", "button[name='delete']", async function () {
    // Firestore의 "members" 컬렉션에서 모든 문서를 가져옵니다.
    const membersSnapshot = await getDocs(collection(db, "members"));

    // 가져온 문서 각각에 대해 ID와 데이터를 콘솔에 출력하고 일치하는 문서를 삭제합니다.
    membersSnapshot.forEach(async (doc) => {
        const row = doc.data(); // 해당 문서의 데이터를 가져옵니다.
        const name = row['name'];

        // name 필드가 data.name과 일치하는 경우
        if (name === data.name) {
            // 일치하는 문서를 삭제합니다.
            await deleteDoc(doc.ref); // doc.ref로 문서 참조를 가져옵니다.
            console.log(doc.id, " => ", row);
        }
    });

    // 삭제 후 UI 업데이트
    document.getElementById("removePop").remove();
    $("#popup").css("display", "none");
    alert('성공적으로 삭제되었습니다!');
});

 

> 오류3

장점, 협업, 창 전환 안됨. <- window.함수.function() {} 로 해결


시도

>오류1

팝업창이 닫히긴 하지만 여전히 이전정보 같이 보입니다.

// 팝업 닫기 버튼 클릭 시 팝업을 닫습니다.        
        $("#clbtn").click(function () {
            $("#popup").css("display", "none");
            // PopCardElement.find('#tempContent').remove();
            PopCardElement = null; // 또는 PopCardElement = undefined;
            $("#popup_content").empty();
            console.log('$("#popup_content").empty();')
        })

에러

membercard copy.html:414 Uncaught ReferenceError: PopCardElement is not defined
    at HTMLButtonElement.<anonymous> (membercard copy.html:414:28)
    at HTMLButtonElement.dispatch (jquery.min.js:2:43090)
    at v.handle (jquery.min.js:2:41074)

 

> 오류2

스크립트 안에서 쓰는 코드가 작동되지 않습니다.

<body> 안의 코드만 작동됩니다,

일단 수정버튼은 페이지 이동만 가능하게 만들어 뒀습니다.

<div class="col">
    <button id="reviseBtn" type="button" class="btn btn-outline-secondary" onclick="location.href='addcard.html'">수정</button>
    <button onclick="console.log('수정화면으로 이동')" id="deleteBtn" type="button" class="btn btn-outline-secondary">삭제</button>
</div>

 

코드인식하는 방법을 찾았습니다.

window.reviseBtn = function() {
    // 원하는 기능
    console.log('페이지 이동')
};


window.deleteBtn = function() {
    // 원하는 기능
    console.log('삭제키 작동')
};

기능 (수정 멤버 정보 들고 페이지 이동, 해당 멤버 삭제) 추가하겠습니다.

 

 

삭제 코드 - '삭제중 오류 발생' . 파이어 베이스를 특정짓지 못한다고 하는데.. 이름이 팝업창과 일치하는 회원의 정보를 어떻게 삭제하지?

오류 메시지 : firebase is not defined

// 모듈 스크립트에서 전역 deleteBtn 함수 생성
window.deleteBtn = async function (name) { 
    try {
        // Firestore의 'members' 컬렉션 참조
        const membersRef = firebase.firestore().collection('members');
        
        // 'members' 컬렉션에서 이름이 일치하는 문서 조회
        const querySnapshot = await membersRef.where('name', '==', name).get();
        
        // 문서가 있을 때 삭제 진행
        if (!querySnapshot.empty) {
            querySnapshot.forEach(async (doc) => {
                await doc.ref.delete();
                console.log(`멤버 ${name} 삭제 완료`);
            });
        } else {
            console.log(`멤버 ${name}을 찾을 수 없습니다.`);
        }
    } catch (error) {
        console.log('삭제 중 오류 발생:'+ error);
    }
};

 

파이어베이스 초기화, 하는거 다 했는데 자꾸 오류가 뜸

TypeError: doc is not a function
    at HTMLButtonElement.<anonymous> (cardmodal.html:399:24)
    at HTMLDocument.dispatch (jquery.min.js:2:43090)
    at v.handle (jquery.min.js:2:41074)

 

팀원들과 합치고 나서 팀원들의 파이어베이스 초기화를 믿고 다시 시도... 그치만 동일한 오류 발생

                //// 삭제 버튼 클릭 함수
                $(document).on("click", "button[name='delete']", async function () {
                // firebase 데이터 다시 읽어오기
                    let membersDb = await getDocs(query(collection(db, "members"), orderBy("name")));
                    membersDb.forEach((docRef) => {
                   // 데이터 조리해서 가져오기
                    let row = docRef.data();
                    let name = row['name'];
                    if (name === `${data.name}`) {
                        deleteDoc(doc(db, "members", docRef.id))
                        alert('성공적으로 삭제되었습니다!');
                        $("#popup").css("display", "none");                      
                    } else {
                    //alert('잘못된 접근입니다.');
                }})

문서 삭제 오류: TypeError: doc is not a function
    at HTMLButtonElement.<anonymous> (cardmodal.js:141:40)
    at HTMLDocument.dispatch (jquery.min.js:2:43090)
    at v.handle (jquery.min.js:2:41074)

 

 

await를 사용해 deleteDoc가 실행될 때 까지 기다리   -> await 줄에서 오류가 발생했습니다.

$(document).on("click", "button[name='delete']", async function () {
    // firebase 데이터 다시 읽어오기
    let membersDb = await getDocs(query(collection(db, "members"), orderBy("name")));
    
    for (let doc2 of membersDb.docs) {  // forEach 대신 for..of 사용
        let row = doc2.data();
        let name = row['name'];
        
        if (name === data.name) {
            await deleteDoc(doc(db, "members", doc2.id));  // await 추가
            document.getElementById("removePop").remove();
            $("#popup").css("display", "none"); 
            alert('성공적으로 삭제되었습니다!');
            break;  // 삭제 후 루프 종료
        }
    }
    
    console.log('삭제 끝');
});

에러메시지

Uncaught (in promise) TypeError: doc is not a function
    at HTMLButtonElement.<anonymous> (cardmodal.js:179:45)
(anonymous) @ cardmodal.js:179
await in (anonymous)
dispatch @ jquery.min.js:2
v.handle @ jquery.min.js:2Understand this errorAI

 

doc is not a function... doc가 아니라 doc2로 해야했을까? 파이어뱅이스 함수가 아니라 변수인걸까?

await deleteDoc(doc2(db, "members", doc2.id));

Uncaught (in promise) TypeError: doc2 is not a function

음.. 아니었음

 

 

where로 찾으려고 했는데 'where'를 import하니 오류가 생겼습니다.

           $(document).on("click", "button[name='delete']", async function () {                
                //Firestore의 "members" 컬렉션에서 name 필드가 data.name과 같은 문서를 검색하는 쿼리를 생성합니다.
                const q = query(collection(db, "members"), where("name", "==", data.name));
                
                //생성한 쿼리를 실행하여 해당하는 문서들의 스냅샷을 가져옵니다.
                const querySnapshot = await getDocs(q);
                
                // 가져온 문서 각각에 대해 ID와 데이터를 콘솔에 출력합니다. doc.data()는 해당 문서의 데이터를 반환합니다.
                querySnapshot.forEach((doc) => { // doc.data() is never undefined for query doc snapshots
                   console.log(doc.id, " => ", doc.data());})
                document.getElementById("removePop").remove();
                $("#popup").css("display", "none"); 
                await deleteDoc(doc(db, "members", q.id));
                alert('성공적으로 삭제되었습니다!');

 

// card modal.js
import {
    db,
    getDocs,
    collection,
    deleteDoc,
    addDoc,
    doc,
    orderBy,
    query,
    where, // 오류발생
} from './firebase.js';

 

그리고 'where'를 추가하니 멤버 카드가 사라졌습니다.

 

 

where빼고 다시 시도

$(document).on("click", "button[name='delete']", async function () {
    // Firestore의 "members" 컬렉션에서 모든 문서를 가져옵니다.
    const membersSnapshot = await getDocs(collection(db, "members"));

    // 가져온 문서 각각에 대해 ID와 데이터를 콘솔에 출력하고 일치하는 문서를 삭제합니다.
    membersSnapshot.forEach(async (doc) => {
        const row = doc.data(); // 해당 문서의 데이터를 가져옵니다.
        const name = row['name'];

        // name 필드가 data.name과 일치하는 경우
        if (name === data.name) {
            // 일치하는 문서를 삭제합니다.
            await deleteDoc(doc.ref); // doc.ref로 문서 참조를 가져옵니다.
            console.log(doc.id, " => ", row);
        }
    });

    // 삭제 후 UI 업데이트
    document.getElementById("removePop").remove();
    $("#popup").css("display", "none");
    alert('성공적으로 삭제되었습니다!');
});

성공!!!

 

이제 수정버튼만 남았습니다!!!

 

 

 

 

 

 

 

 

 

 

 

 

 

 


기억하기

 

◆ 변수 삭제

//let, const로 선언한 경우
PopCardElement = null; // 또는
PopCardElement = undefined;

//var로 선언한 경우
delete PopCardElement;

 

◆ id로 <dev> 삭제하기

document.getElementById("id이름").remove();

 

◆ 같은 폴더의 다른html 파일로 이동하기

<button type="button" onclick="location.href='second.html'">이동1</button>

<button type="button">
    <a class="p-2 text-muted" href="/._includes/addcard.html">이동2</a></button>

 

 

제이쿼리(jQuery) 라이브러리와 다른 자바스크립트(javascript) 라이브러리를 동시 사용했을 때  발생하는 충돌 해결하기

1. 제이쿼리를 사용하기 전에 jQuery.noConflict() 이 메서드를 이용하여 $ 이 기호를 대처할만한 다른 변수에 저장합니다.

2. 다른 변수에 저장한 $jQ 변수를 제이쿼리 기호로 사용합니다.

사용은 무조건 제이쿼리를 사용하기 전에 jQuery.noConflict() 이 메서드를 이용하여 새로운 변수를 지정하여 사용해야합니다.

https://knowing-passion.tistory.com/66#google_vignette

jQuery.noConflict(); // 충돌방지

기존 $ 이 기호 하나를 이용해서 제이쿼리를 이용했는데 충돌이 일어나니 JQury $ 기호를 $jQ 이걸로 치환해서 사용합니다.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <script src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.3/prototype.js"></script>
  <script src="https://code.jquery.com/jquery-3.1.0.js"></script>
  <script type="text/javascript">
        var $jQ = jQuery.noConflict();
         $jQ(document).ready(function(){
            $jQ('h1').text('충돌방지 해결');
        });        
  </script>
</head>
<body>
      
</body>
</html>

 

 

 

 

 

전역 객체를 활용하는 방법
모듈 스크립트(type="module")에서 정의한 함수나 변수는 기본적으로 모듈 스코프 내에서만 유효합니다. 즉, 다른 일반 스크립트나 jQuery로 동적으로 추가한 DOM 요소에서 모듈 스코프에 있는 코드를 바로 접근하기 어렵습니다

// module.js
window.someFunction = function() {
    // 원하는 기능
};
<!--사용-->
<button onclick='someFunction()' ...

 

◆ 파이어베이스

https://duckgugong.tistory.com/208

 

 

◆ 파이어스토어 다큐멘트 삭제

const res = await db.collection('cities').doc('DC').delete();

 

 

◆ break; 오류 : 점프 대상은 함수 경계를 벗어날 수 없습니다.

https://hsly22xk.tistory.com/387

 forEach()나 함수 등 for loop 바깥쪽에 break/continue를 사용하려고 할 때 발생하는 오류입니다.

 

 

◆파이어베이스 컬렉션의 여러 문서 가져오기

https://firebase.google.com/docs/firestore/query-data/get-data?hl=ko#web

import { collection, query, where, getDocs } from "firebase/firestore";

const q = query(collection(db, "cities"), where("capital", "==", true));

const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
  // doc.data() is never undefined for query doc snapshots
  console.log(doc.id, " => ", doc.data());
});

 

 

 

 

◆ 

 

 

◆ 

 

 

◆ 

 

 

◆ 

 

 

◆ 

 

 

◆ 

 

 

◆ 

 

 

◆ 

 

 

◆ 

 

 





◆  ◆  ◆  ◆  ◆  ◆  ◆  ◆  ◆  ◆  ◆  ◆  ◆  ◆  ◆  ◆  ◆  ◆  ◆  ◆  ◆  ◆  ◆  ◆  ◆  ◆  ◆  ◆