내일배움캠프 4일차(Firebase)

박화랑·2025년 2월 20일
0

Spring_6기

목록 보기
2/15

Firebase를 활용한 팀원 프로필 페이지 개발기

프로젝트 개요

Spring 6기 32조의 팀원 프로필 페이지를 개발하면서 Firebase Firestore를 이용해 데이터를 동적으로 불러오고, 사용자 입력을 저장하는 기능을 구현했다.
이 과정에서 팀원 목록, 프로젝트 관리, 문의하기 기능을 개발했으며, 진행 중 발생한 문제와 해결 방법도 함께 정리했다.


1️⃣ 팀원 프로필 페이지 구현

기능 개요

  • Firebase Firestore에서 teamMembers 데이터를 불러와 프로필 페이지를 동적으로 생성
  • 클릭 시 team.html?name=팀원이름 형태로 이동하여 개별 프로필을 보여줌

Firebase에서 팀원 목록 불러오기

$(document).ready(async function () {
    const querySnapshot = await getDocs(collection(db, 'teamMembers'));

    querySnapshot.forEach((doc) => {
        let data = doc.data();

        let memberCard = `
            <div class="col-md-4">
                <div class="card shadow-sm text-center p-4">
                    <img src="${data.profileImage}" class="rounded-circle mx-auto d-block" width="150" height="150" alt="프로필 이미지">
                    <h4 class="mt-3 fw-bold">${data.name}</h4>
                    <p class="text-muted">${data.role ? data.role : '직책 미정'}</p>
                    <button class="btn btn-primary btn-sm"
                        style="padding: 6px 16px; font-size: 0.9rem; width: fit-content; min-width: unset; display: block; margin: 0 auto;"
                       token interpolation">${encodeURIComponent(data.name)}';">
                        자세히 보기
                    </button>
                </div>
            </div>
        `;
        $('#teamList').append(memberCard);
    });
});

문제 상황: 프로필 사진이 너무 작게 나옴

  • 기본적으로 img 태그의 크기를 100px로 설정했더니 너무 작아 보였음.
  • 해결 방법: 사진 크기를 150px로 조정하고, object-fit: cover;을 추가하여 비율 유지
img.rounded-circle {
    width: 150px;
    height: 150px;
    object-fit: cover;
}

2️⃣ 프로젝트 목록 동적 생성

기능 개요

  • Firebase projects 컬렉션에서 데이터를 가져와 프로젝트 리스트를 표시
  • 프로젝트 클릭 시 상세 페이지 또는 GitHub Repository로 이동

Firebase에서 프로젝트 리스트 불러오기

$(document).ready(async function () {
    const querySnapshot = await getDocs(collection(db, 'projects'));

    let projectHTML = '';

    querySnapshot.forEach((doc) => {
        let data = doc.data();

        projectHTML += `
            <div class="feature col">
                <h3 class="fs-2 text-body-emphasis">${data.title}</h3>
                <p>${data.description}</p>
                <a href="${data.link}" target="_blank" class="icon-link">
                    자세히 보기
                    <svg class="bi">
                        <use xlink:href="#chevron-right"></use>
                    </svg>
                </a>
            </div>
        `;
    });

    $('#projectList').html(projectHTML);
});

문제 상황: 프로젝트 내용이 고정된 텍스트로 표시됨

  • HTML에 하드코딩된 프로젝트 정보가 계속 나왔음
  • 해결 방법: Firebase에서 프로젝트 데이터를 동적으로 가져와 리스트를 갱신하도록 코드 수정

3️⃣ 문의하기 (Contact US) 기능 구현

기능 개요

  • 사용자가 이메일과 문의 내용을 입력하면 Firebase Firestore에 저장
  • 입력이 완료되면 성공 메시지를 표시하고 입력 필드를 초기화

Firebase에 문의 내용 저장

import { addDoc, collection } from 'https://www.gstatic.com/firebasejs/9.22.0/firebase-firestore.js';

document.getElementById('contactForm').addEventListener('submit', async function (event) {
    event.preventDefault(); // 기본 폼 제출 방지

    let email = document.getElementById('contactEmail').value.trim();
    let message = document.getElementById('contactMessage').value.trim();

    if (!email || !message) {
        alert('❌ 이메일과 문의 내용을 입력해주세요.');
        return;
    }

    try {
        await addDoc(collection(db, 'inquiries'), {
            email: email,
            message: message,
            timestamp: new Date()
        });

        alert('✅ 문의가 성공적으로 제출되었습니다.');
        document.getElementById('contactForm').reset();
    } catch (error) {
        console.error('문의 저장 실패:', error);
        alert('❌ 문의 제출 중 오류가 발생했습니다.');
    }
});

문제 상황: 폼 제출 후 입력값이 그대로 남아있음

  • 사용자가 문의를 제출한 후에도 입력 필드가 비워지지 않음
  • 해결 방법: 성공적으로 저장된 후 reset() 메서드를 호출하여 폼 초기화
document.getElementById('contactForm').reset();

4️⃣ fetch를 이용한 데이터 요청

기능 개요

  • Firestore에 직접 접근하는 대신, Cloud Functions API를 활용하여 데이터를 가져오기
  • fetch를 사용하여 Firebase에서 데이터를 요청

fetch를 이용한 프로젝트 목록 가져오기

async function loadProjects() {
    try {
        let response = await fetch("https://us-central1-YOUR_PROJECT_ID.cloudfunctions.net/getProjects");
        let projects = await response.json();

        let projectHTML = '';
        projects.forEach((data) => {
            projectHTML += `
                <div class="feature col">
                    <h3 class="fs-2 text-body-emphasis">${data.title}</h3>
                    <p>${data.description}</p>
                    <a href="${data.link}" target="_blank" class="icon-link">
                        자세히 보기
                        <svg class="bi">
                            <use xlink:href="#chevron-right"></use>
                        </svg>
                    </a>
                </div>
            `;
        });

        document.getElementById('projectList').innerHTML = projectHTML;
    } catch (error) {
        console.error("Error loading projects:", error);
    }
}

// 페이지 로드 시 실행
loadProjects();

문제 상황: Firebase에서 직접 데이터를 가져올 때 보안 문제가 발생할 수 있음

  • getDocs()로 데이터를 직접 가져오면 클라이언트에서 Firestore를 수정할 가능성이 있음
  • 해결 방법: Cloud Functions API를 활용하여 fetch를 통한 데이터 요청으로 변경

배운 점 & 결론

Firestore에서 데이터를 동적으로 가져와 렌더링하는 방법을 배웠다.
Firebase를 직접 호출하는 것과 fetch를 통한 API 요청 방식의 차이를 이해했다.
폼 제출 후 입력 필드를 초기화하는 방법을 적용했다.
프로필 페이지 UI를 개선하고, 가독성을 높였다.

이제 Firebase를 활용한 CRUD 구현을 더 발전시켜, 인증 기능도 추가할 수 있으면 좋겠다!
성공적인 결과물!


profile
개발자 희망생

0개의 댓글

관련 채용 정보