AI로 러닝(Learn) 내일을 향해 러닝(Running)

원당컴퓨터학원에서 배우는 AI, 세상을 향해 달리다

데이터베이스

[Firebase] 3장 Cloud firestore 데이터베이스 실습

파아란기쁨1 2025. 8. 23. 09:17
반응형

 

🎪 우리만의 메시지 게시판 놀이공원 만들기

우리가 만들 게시판을 놀이공원의 특별한 메시지 보드라고 생각해보세요!

  • 📝 글쓰기 부스: 새로운 메시지 작성
  • 👀 메시지 보드: 모든 메시지들을 실시간으로 보기
  • ✏️ 수정 코너: 내가 쓴 메시지 고치기
  • 🗑️ 삭제 버튼: 필요없는 메시지 지우기

🏗️ 먼저 Firestore 설정하기

1단계: Firebase 콘솔에서 Firestore 활성화

  1. Firebase 콘솔 접속
  2. 여러분의 프로젝트 클릭
  3. 왼쪽 메뉴에서 "Firestore Database" 클릭
  4. "데이터베이스 만들기" 버튼 클릭
  5. "테스트 모드에서 시작" 선택 (나중에 보안 규칙 설정 가능)
  6. "완료" 클릭

이제 우리만의 데이터 창고가 생겼어요! 📦

🎨 완전한 게시판 시스템 만들기

Firebase Firestore 게시판 시스템
대화형 아티팩트 
 

🎯 코드 설명 - 각 기능별로 쉽게 이해하기

📝 글쓰기 (writeMessage 함수)

 
 
javascript
async function writeMessage() {
    // 1️⃣ 사용자가 입력한 내용 가져오기
    const title = document.getElementById('messageTitle').value;
    const content = document.getElementById('messageContent').value;
    const author = document.getElementById('messageAuthor').value;
    
    // 2️⃣ Firestore 데이터베이스에 새 문서 추가
    await db.collection('messages').add({
        title: title,           // 제목
        content: content,       // 내용  
        author: author,         // 작성자
        createdAt: firebase.firestore.FieldValue.serverTimestamp() // 작성 시간
    });
    
    console.log("🎉 메시지가 데이터베이스에 저장되었어요!");
}

👀 실시간 목록 조회 (onSnapshot)

 
 
javascript
// Firebase의 마법! 데이터가 바뀔 때마다 자동으로 알려줌
db.collection('messages')
  .orderBy('createdAt', 'desc')  // 최신 메시지부터 정렬
  .onSnapshot((snapshot) => {
      console.log("🔄 데이터가 업데이트되었어요!");
      
      // 변경된 내용을 화면에 표시
      displayMessages(snapshot.docs);
  });

✏️ 글 수정 (update 함수)

 
 
javascript
async function saveEdit(messageId) {
    // 수정된 내용 가져오기
    const newTitle = document.getElementById(`edit-title-${messageId}`).value;
    
    // Firestore에서 해당 문서 업데이트
    await db.collection('messages').doc(messageId).update({
        title: newTitle,
        updatedAt: firebase.firestore.FieldValue.serverTimestamp()
    });
    
    console.log("✏️ 메시지가 수정되었어요!");
}

🗑️ 글 삭제 (delete 함수)

 
 
javascript
async function deleteMessage(messageId) {
    // 정말 삭제할 건지 확인
    if (confirm("정말 삭제하시겠어요?")) {
        // Firestore에서 문서 삭제
        await db.collection('messages').doc(messageId).delete();
        console.log("🗑️ 메시지가 삭제되었어요!");
    }
}

🎪 Firestore 데이터 구조 이해하기

우리의 게시판 데이터는 이렇게 저장돼요:

 
 
🗄️ Firestore Database
└── 📁 messages (컬렉션)
    ├── 📄 문서1 (자동 생성 ID)
    │   ├── title: "첫 번째 메시지"
    │   ├── content: "안녕하세요!"
    │   ├── author: "김철수"  
    │   ├── createdAt: 2024-08-23 14:30:00
    │   └── updatedAt: 2024-08-23 14:30:00
    ├── 📄 문서2
    │   ├── title: "두 번째 메시지"
    │   └── ...
    └── 📄 문서3...

🛠️ 실제로 사용해보기

 

1단계: Firebase 설정 넣기

코드에서 이 부분을 여러분의 실제 설정으로 바꿔주세요:

 
 
javascript
const firebaseConfig = {
    apiKey: "your-actual-api-key",
    authDomain: "your-project.firebaseapp.com",
    projectId: "your-actual-project-id",
    storageBucket: "your-project.appspot.com",
    messagingSenderId: "123456789",
    appId: "your-actual-app-id"
};

2단계: Firestore 보안 규칙 설정 (중요!)

Firebase 콘솔에서:

  1. Firestore Database규칙 탭 클릭
  2. 아래 규칙을 복사해서 붙여넣기:
 
 
javascript
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // messages 컬렉션에 대한 규칙
    match /messages/{document} {
      // 모든 사람이 읽기 가능
      allow read: if true;
      // 모든 사람이 쓰기, 수정, 삭제 가능 (테스트용)
      allow write: if true;
    }
  }
}
  1. "게시" 버튼 클릭

3단계: 테스트해보기!

  1. HTML 파일을 브라우저에서 열기
  2. F12 눌러서 콘솔 열기
  3. 첫 번째 메시지 작성해보기:
    • 제목: "첫 번째 메시지!"
    • 내용: "안녕하세요! 테스트 메시지예요."
    • 작성자: "테스터"

🎯 각각의 마법이 어떻게 작동하는지

🔄 실시간 업데이트의 비밀

Firebase Firestore는 마법의 전령같아요!

 
 
javascript
// 이 한 줄이 마법을 만들어요!
db.collection('messages').onSnapshot((snapshot) => {
    // 누군가 메시지를 추가/수정/삭제하면 즉시 알려줌!
});

실시간 작동 원리:

  1. 👀 누군가 새 메시지를 써요
  2. 🔄 Firestore가 "새 메시지 있어요!" 알림
  3. 📺 모든 사용자의 화면이 자동으로 업데이트!

📊 데이터 저장 방식

 
 
javascript
// 이렇게 저장해요
{
    title: "재미있는 이야기",        // 문자열
    content: "오늘은 날씨가...",     // 문자열  
    author: "김철수",              // 문자열
    createdAt: Timestamp,          // 시간 (Firebase가 자동 생성)
    updatedAt: Timestamp           // 수정 시간
}

🎮 고급 기능들 이해하기

🔍 데이터 정렬하기

 
 
javascript
// 최신 순으로 정렬
.orderBy('createdAt', 'desc')

// 제목 순으로 정렬 (가나다순)  
.orderBy('title', 'asc')

// 작성자 순으로 정렬
.orderBy('author', 'asc')

📄 페이지네이션 (많은 데이터 처리)

 
 
javascript
// 처음 10개만 가져오기
db.collection('messages')
  .orderBy('createdAt', 'desc')
  .limit(10)

🔎 데이터 검색하기

 
 
javascript
// 특정 작성자의 메시지만 찾기
db.collection('messages')
  .where('author', '==', '김철수')
  .get()

🚨 문제 해결 가이드

😢 "permission-denied" 에러

→ Firestore 보안 규칙을 확인하세요! 위의 2단계 규칙을 적용했나요?

😅 메시지가 안 보여요

→ F12 → Console에서 에러 확인하고, Firebase 설정이 정확한지 확인하세요!

🔄 실시간 업데이트가 안 돼요

→ 인터넷 연결 상태와 Firestore가 활성화되었는지 확인하세요!

💾 데이터가 저장 안 돼요

→ Firestore Database가 "테스트 모드"로 설정되었는지 확인하세요!

🌟 재미있는 실험해보기

🎪 다중 브라우저 테스트

  1. 같은 페이지를 두 개의 브라우저에서 열어보세요
  2. 한쪽에서 메시지를 작성하면
  3. 다른 쪽에서 실시간으로 나타나는 걸 볼 수 있어요! ✨

📱 모바일에서도 테스트

  1. 핸드폰 브라우저에서도 열어보세요
  2. 컴퓨터와 핸드폰이 실시간으로 동기화되는 걸 확인하세요!

🔍 Firebase 콘솔에서 데이터 확인

  1. Firebase 콘솔 → Firestore Database로 가세요
  2. 여러분이 작성한 메시지들이 실제로 저장되어 있는 걸 볼 수 있어요!

🎉 축하해요! 완성된 기능들

이제 여러분은:

  • Firestore 데이터베이스에 데이터를 저장할 수 있어요
  • 실시간으로 데이터 변화를 감지할 수 있어요
  • CRUD 기능 (Create, Read, Update, Delete)을 모두 구현했어요
  • 사용자 친화적인 UI로 게시판을 만들었어요
  • 에러 처리사용자 피드백을 제공할 수 있어요

🚀 다음 단계 아이디어

🎨 더 발전시켜보기

  • 📸 이미지 업로드 기능 추가
  • 👍 좋아요/싫어요 버튼 추가
  • 💬 댓글 시스템 만들기
  • 🔐 사용자 인증과 연결하기
  • 🏷️ 태그카테고리 기능
  • 🔍 검색 기능 강화

🎪 다른 종류의 앱 만들기

  • 📝 할일 관리 앱
  • 💬 채팅 앱
  • 📚 온라인 일기장
  • 🎮 게임 점수판

 

전체 코드

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>🎪 놀이공원 메시지 게시판</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Comic Sans MS', cursive;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            min-height: 100vh;
            padding: 20px;
        }

        .container {
            max-width: 1000px;
            margin: 0 auto;
        }

        h1 {
            text-align: center;
            font-size: 2.5em;
            margin: 20px 0;
            text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
        }

        .carnival {
            text-align: center;
            font-size: 3em;
            margin: 20px;
            animation: bounce 2s ease-in-out infinite;
        }

        @keyframes bounce {
            0%, 100% { transform: translateY(0px); }
            50% { transform: translateY(-15px); }
        }

        .section {
            background: rgba(255, 255, 255, 0.1);
            backdrop-filter: blur(10px);
            border-radius: 20px;
            padding: 30px;
            margin: 20px 0;
            box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
        }

        .write-section {
            background: linear-gradient(135deg, rgba(255, 107, 53, 0.3), rgba(247, 147, 30, 0.3));
        }

        .board-section {
            background: linear-gradient(135deg, rgba(76, 175, 80, 0.3), rgba(139, 195, 74, 0.3));
        }

        .form-group {
            margin: 15px 0;
        }

        label {
            display: block;
            margin-bottom: 8px;
            font-weight: bold;
            font-size: 1.1em;
        }

        input, textarea {
            width: 100%;
            padding: 12px;
            border: none;
            border-radius: 10px;
            font-size: 1em;
            background: rgba(255, 255, 255, 0.9);
            color: #333;
            font-family: inherit;
        }

        input:focus, textarea:focus {
            outline: none;
            box-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
            transform: scale(1.02);
        }

        textarea {
            height: 120px;
            resize: vertical;
        }

        button {
            background: linear-gradient(45deg, #ff6b35, #f7931e);
            color: white;
            border: none;
            padding: 12px 20px;
            border-radius: 25px;
            font-size: 1em;
            cursor: pointer;
            margin: 5px;
            transition: all 0.3s ease;
            font-weight: bold;
            font-family: inherit;
        }

        button:hover {
            transform: translateY(-2px);
            box-shadow: 0 5px 15px rgba(0,0,0,0.2);
        }

        .btn-edit {
            background: linear-gradient(45deg, #2196F3, #21CBF3);
            padding: 8px 15px;
            font-size: 0.9em;
        }

        .btn-delete {
            background: linear-gradient(45deg, #e74c3c, #c0392b);
            padding: 8px 15px;
            font-size: 0.9em;
        }

        .btn-cancel {
            background: linear-gradient(45deg, #95a5a6, #7f8c8d);
        }

        .message-card {
            background: rgba(255, 255, 255, 0.15);
            border-radius: 15px;
            padding: 20px;
            margin: 15px 0;
            transition: transform 0.3s ease;
            border-left: 5px solid #ffd700;
        }

        .message-card:hover {
            transform: scale(1.02);
        }

        .message-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
            flex-wrap: wrap;
        }

        .message-title {
            font-size: 1.3em;
            font-weight: bold;
            color: #ffd700;
            margin-bottom: 5px;
        }

        .message-author {
            font-size: 0.9em;
            color: #b3b3b3;
        }

        .message-date {
            font-size: 0.8em;
            color: #999;
        }

        .message-content {
            background: rgba(255, 255, 255, 0.1);
            padding: 15px;
            border-radius: 10px;
            margin: 10px 0;
            line-height: 1.6;
        }

        .message-actions {
            display: flex;
            gap: 10px;
            flex-wrap: wrap;
        }

        .status-message {
            padding: 15px;
            border-radius: 10px;
            margin: 15px 0;
            font-weight: bold;
            text-align: center;
        }

        .success {
            background: rgba(76, 175, 80, 0.3);
            border: 1px solid #4CAF50;
        }

        .error {
            background: rgba(244, 67, 54, 0.3);
            border: 1px solid #f44336;
        }

        .info {
            background: rgba(33, 150, 243, 0.3);
            border: 1px solid #2196F3;
        }

        .loading {
            text-align: center;
            padding: 40px;
        }

        .loading-spinner {
            font-size: 2em;
            animation: spin 2s linear infinite;
        }

        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }

        .empty-message {
            text-align: center;
            padding: 40px;
            color: #b3b3b3;
        }

        .edit-form {
            background: rgba(33, 150, 243, 0.2);
            border: 2px solid #2196F3;
            border-radius: 15px;
            padding: 20px;
            margin-top: 15px;
        }

        @media (max-width: 768px) {
            .container {
                padding: 10px;
            }
            
            h1 {
                font-size: 2em;
            }
            
            .message-header {
                flex-direction: column;
                align-items: flex-start;
            }
            
            .message-actions {
                justify-content: center;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>🎪 놀이공원 메시지 게시판</h1>
        <div class="carnival">🎡🎢🎠</div>
        
        <!-- 상태 메시지 -->
        <div id="statusMessage"></div>
        
        <!-- 글쓰기 섹션 -->
        <div class="section write-section">
            <h2>📝 새로운 메시지 작성하기</h2>
            <div class="form-group">
                <label>🎯 제목 (어떤 이야기인가요?):</label>
                <input type="text" id="messageTitle" placeholder="재미있는 제목을 써주세요!" maxlength="100">
            </div>
            <div class="form-group">
                <label>📖 내용 (자세히 이야기해주세요!):</label>
                <textarea id="messageContent" placeholder="여러분의 이야기를 들려주세요! 오늘 뭘 했는지, 어떤 기분인지..." maxlength="1000"></textarea>
            </div>
            <div class="form-group">
                <label>✍️ 작성자 (누가 쓰는 메시지인가요?):</label>
                <input type="text" id="messageAuthor" placeholder="여러분의 이름이나 별명을 써주세요!" maxlength="50">
            </div>
            <button onclick="writeMessage()">🎪 메시지 게시판에 올리기!</button>
            <button onclick="clearForm()" class="btn-cancel">🧹 다시 쓰기</button>
        </div>
        
        <!-- 게시판 섹션 -->
        <div class="section board-section">
            <h2>👀 모든 메시지 보기 (실시간 업데이트!)</h2>
            <div id="refreshStatus" class="info status-message">
                🔄 실시간으로 새 메시지를 확인하고 있어요!
            </div>
            <div id="messagesContainer">
                <div class="loading">
                    <div class="loading-spinner">🔄</div>
                    <p>메시지들을 불러오고 있어요...</p>
                </div>
            </div>
        </div>
    </div>

    <!-- Firebase SDK -->
    <script src="https://www.gstatic.com/firebasejs/10.7.1/firebase-app.js"></script>
    <script src="https://www.gstatic.com/firebasejs/10.7.1/firebase-firestore.js"></script>
    
    <script>
        // 🔑 Firebase 설정 (여기에 여러분의 실제 설정을 넣어주세요!)
        const firebaseConfig = {
            apiKey: "your-api-key-here",
            authDomain: "your-project.firebaseapp.com",
            projectId: "your-project-id",
            storageBucket: "your-project.appspot.com",
            messagingSenderId: "123456789",
            appId: "your-app-id-here"
        };

        // 🚀 Firebase 초기화
        let app;
        let db;
        let messagesListener = null;
        
        try {
            app = firebase.initializeApp(firebaseConfig);
            db = firebase.firestore();
            console.log("🎉 Firebase와 Firestore 준비 완료!");
            showStatus("🎉 놀이공원 게시판이 준비되었어요!", "success");
            
            // 실시간 메시지 감지 시작
            startRealTimeListener();
            
        } catch (error) {
            console.error("😢 Firebase 초기화 실패:", error);
            showStatus("😢 놀이공원 준비 중 오류가 발생했어요. 설정을 확인해주세요!", "error");
        }

        // 📝 새 메시지 작성 함수
        async function writeMessage() {
            const title = document.getElementById('messageTitle').value.trim();
            const content = document.getElementById('messageContent').value.trim();
            const author = document.getElementById('messageAuthor').value.trim();

            // 입력값 검사
            if (!title) {
                showStatus("😅 제목을 써주세요!", "error");
                return;
            }
            if (!content) {
                showStatus("😅 내용을 써주세요!", "error");
                return;
            }
            if (!author) {
                showStatus("😅 작성자 이름을 써주세요!", "error");
                return;
            }

            console.log("📝 새 메시지 작성 시작...");
            showStatus("✨ 메시지를 게시판에 올리고 있어요...", "info");

            try {
                // Firestore에 새 문서 추가
                const docRef = await db.collection('messages').add({
                    title: title,
                    content: content,
                    author: author,
                    createdAt: firebase.firestore.FieldValue.serverTimestamp(),
                    updatedAt: firebase.firestore.FieldValue.serverTimestamp()
                });

                console.log("🎉 메시지 작성 성공! ID:", docRef.id);
                showStatus("🎉 메시지가 게시판에 올라갔어요!", "success");
                clearForm();

            } catch (error) {
                console.error("😢 메시지 작성 실패:", error);
                showStatus("😢 메시지 올리기에 실패했어요. 다시 시도해주세요!", "error");
            }
        }

        // 👀 실시간 메시지 감지 시작
        function startRealTimeListener() {
            console.log("👀 실시간 메시지 감지 시작!");
            
            // Firestore에서 실시간으로 데이터 감지
            messagesListener = db.collection('messages')
                .orderBy('createdAt', 'desc') // 최신 메시지부터
                .onSnapshot((snapshot) => {
                    console.log("🔄 메시지 업데이트 감지! 변경된 문서 수:", snapshot.docChanges().length);
                    
                    // 변경 사항 로그
                    snapshot.docChanges().forEach((change) => {
                        if (change.type === 'added') {
                            console.log("➕ 새 메시지 추가:", change.doc.data().title);
                        } else if (change.type === 'modified') {
                            console.log("✏️ 메시지 수정:", change.doc.data().title);
                        } else if (change.type === 'removed') {
                            console.log("🗑️ 메시지 삭제됨");
                        }
                    });
                    
                    displayMessages(snapshot.docs);
                }, (error) => {
                    console.error("😢 실시간 감지 오류:", error);
                    showStatus("😢 실시간 업데이트 중 오류가 발생했어요.", "error");
                });
        }

        // 🖥️ 메시지들을 화면에 표시
        function displayMessages(docs) {
            const container = document.getElementById('messagesContainer');
            
            if (docs.length === 0) {
                container.innerHTML = `
                    <div class="empty-message">
                        <h3>📭 아직 메시지가 없어요!</h3>
                        <p>첫 번째 메시지를 작성해보세요! 🌟</p>
                    </div>
                `;
                return;
            }

            let html = '';
            docs.forEach((doc) => {
                const data = doc.data();
                const createdAt = data.createdAt ? 
                    data.createdAt.toDate().toLocaleString('ko-KR') : 
                    '방금 전';

                html += `
                    <div class="message-card" id="message-${doc.id}">
                        <div class="message-header">
                            <div>
                                <div class="message-title">${escapeHtml(data.title)}</div>
                                <div class="message-author">✍️ ${escapeHtml(data.author)}</div>
                            </div>
                            <div class="message-date">📅 ${createdAt}</div>
                        </div>
                        <div class="message-content">${escapeHtml(data.content).replace(/\n/g, '<br>')}</div>
                        <div class="message-actions">
                            <button class="btn-edit" onclick="startEdit('${doc.id}', '${escapeHtml(data.title)}', '${escapeHtml(data.content)}', '${escapeHtml(data.author)}')">
                                ✏️ 수정하기
                            </button>
                            <button class="btn-delete" onclick="deleteMessage('${doc.id}', '${escapeHtml(data.title)}')">
                                🗑️ 삭제하기
                            </button>
                        </div>
                        <div id="edit-${doc.id}" class="edit-form" style="display: none;">
                            <!-- 수정 폼이 여기에 동적으로 추가됩니다 -->
                        </div>
                    </div>
                `;
            });

            container.innerHTML = html;
            console.log("🖥️ 메시지 화면 업데이트 완료! 총", docs.length, "개");
        }

        // ✏️ 메시지 수정 시작
        function startEdit(messageId, title, content, author) {
            console.log("✏️ 메시지 수정 모드 시작:", messageId);
            
            const editContainer = document.getElementById(`edit-${messageId}`);
            editContainer.style.display = 'block';
            editContainer.innerHTML = `
                <h3>✏️ 메시지 수정하기</h3>
                <div class="form-group">
                    <label>🎯 제목:</label>
                    <input type="text" id="edit-title-${messageId}" value="${title}" maxlength="100">
                </div>
                <div class="form-group">
                    <label>📖 내용:</label>
                    <textarea id="edit-content-${messageId}" maxlength="1000">${content}</textarea>
                </div>
                <div class="form-group">
                    <label>✍️ 작성자:</label>
                    <input type="text" id="edit-author-${messageId}" value="${author}" maxlength="50">
                </div>
                <button onclick="saveEdit('${messageId}')">💾 수정 완료!</button>
                <button onclick="cancelEdit('${messageId}')" class="btn-cancel">❌ 취소</button>
            `;
            
            // 수정 중임을 알리기
            showStatus("✏️ 수정 모드입니다. 내용을 바꾸고 '수정 완료'를 눌러주세요!", "info");
        }

        // 💾 메시지 수정 저장
        async function saveEdit(messageId) {
            const title = document.getElementById(`edit-title-${messageId}`).value.trim();
            const content = document.getElementById(`edit-content-${messageId}`).value.trim();
            const author = document.getElementById(`edit-author-${messageId}`).value.trim();

            if (!title || !content || !author) {
                showStatus("😅 모든 칸을 채워주세요!", "error");
                return;
            }

            console.log("💾 메시지 수정 저장:", messageId);
            showStatus("✨ 메시지를 수정하고 있어요...", "info");

            try {
                await db.collection('messages').doc(messageId).update({
                    title: title,
                    content: content,
                    author: author,
                    updatedAt: firebase.firestore.FieldValue.serverTimestamp()
                });

                console.log("🎉 메시지 수정 완료!");
                showStatus("🎉 메시지가 수정되었어요!", "success");
                cancelEdit(messageId);

            } catch (error) {
                console.error("😢 메시지 수정 실패:", error);
                showStatus("😢 메시지 수정에 실패했어요. 다시 시도해주세요!", "error");
            }
        }

        // ❌ 수정 취소
        function cancelEdit(messageId) {
            console.log("❌ 메시지 수정 취소:", messageId);
            document.getElementById(`edit-${messageId}`).style.display = 'none';
        }

        // 🗑️ 메시지 삭제
        async function deleteMessage(messageId, title) {
            // 정말 삭제할 건지 확인
            if (!confirm(`🗑️ 정말 "${title}" 메시지를 삭제하시겠어요?\n\n삭제하면 다시 되돌릴 수 없어요!`)) {
                return;
            }

            console.log("🗑️ 메시지 삭제 시작:", messageId);
            showStatus("🗑️ 메시지를 삭제하고 있어요...", "info");

            try {
                await db.collection('messages').doc(messageId).delete();
                
                console.log("🎉 메시지 삭제 완료!");
                showStatus("🎉 메시지가 삭제되었어요!", "success");

            } catch (error) {
                console.error("😢 메시지 삭제 실패:", error);
                showStatus("😢 메시지 삭제에 실패했어요. 다시 시도해주세요!", "error");
            }
        }

        // 🧹 입력 폼 정리
        function clearForm() {
            document.getElementById('messageTitle').value = '';
            document.getElementById('messageContent').value = '';
            document.getElementById('messageAuthor').value = '';
            console.log("🧹 입력 폼을 깨끗하게 정리했어요!");
        }

        // 📢 상태 메시지 표시
        function showStatus(message, type) {
            const statusDiv = document.getElementById('statusMessage');
            statusDiv.innerHTML = `<div class="status-message ${type}">${message}</div>`;
            
            // 5초 후 성공/에러 메시지 자동 삭제 (info는 유지)
            if (type !== 'info') {
                setTimeout(() => {
                    statusDiv.innerHTML = '';
                }, 5000);
            }
        }

        // 🛡️ HTML 이스케이프 (보안을 위해)
        function escapeHtml(text) {
            const div = document.createElement('div');
            div.textContent = text;
            return div.innerHTML.replace(/'/g, '&#39;');
        }

        // 🎮 페이지 언로드 시 리스너 정리
        window.addEventListener('beforeunload', () => {
            if (messagesListener) {
                console.log("🧹 실시간 리스너를 정리합니다");
                messagesListener();
            }
        });

        // 🌟 페이지 로드 시 안내
        window.onload = function() {
            console.log("🎪 놀이공원 게시판에 오신 걸 환영해요!");
            console.log("🎯 기능 안내:");
            console.log("   📝 메시지 작성: 제목, 내용, 작성자를 입력하고 '올리기' 클릭");
            console.log("   👀 실시간 조회: 다른 사람이 메시지를 올리면 자동으로 보여져요");
            console.log("   ✏️ 메시지 수정: '수정하기' 버튼으로 내용 바꾸기");
            console.log("   🗑️ 메시지 삭제: '삭제하기' 버튼으로 메시지 지우기");
            console.log("   🔄 모든 변화가 실시간으로 반영돼요!");
            
            showStatus("🎪 놀이공원 메시지 게시판에 오신 걸 환영해요! 첫 메시지를 작성해보세요!", "info");
        };
    </script>
</body>
</html>

 

반응형