Firebase 실시간 DB로 학생 응답 수집 | 퀴즈 결과 자동 저장 — 교사용 가이드

📌 이 글 요약

  • Firebase Realtime Database를 사용하면 학생의 퀴즈 점수, 응답 내용을 자동으로 수집할 수 있습니다.
  • HTML 교구에 JS 코드 10줄만 추가하면 됩니다. 서버 구축 불필요.
  • 데이터는 Firebase Console에서 실시간으로 확인 가능 — 새로고침도 필요 없어요.
  • 무료 요금제(Spark Plan)로 충분합니다. 동시 접속 100명, 저장 1GB.

교구를 만들었는데, 학생이 몇 점 받았는지 어떻게 알죠? Firebase Realtime DB를 연결하면 자동으로 수집됩니다.

퀴즈 교구를 배포하고 나면 항상 같은 질문이 생깁니다. "학생들이 실제로 풀었는지, 몇 점 받았는지 어떻게 확인하지?" 구글 설문지를 따로 만들자니 번거롭고, 교구 안에서 바로 저장되면 좋겠는데 — 바로 그게 Firebase Realtime Database가 해주는 일입니다.

이전 글에서 Firebase Hosting으로 교구를 배포하는 방법을 다뤘습니다. 이번에는 그 교구에 데이터 저장 기능을 붙이겠습니다.

왜 Realtime Database가 필요한가요?

교사가 HTML 퀴즈 교구를 만들어 배포하면, 학생은 브라우저에서 문제를 풀고 점수를 확인합니다. 그런데 그 점수는 학생의 브라우저 안에서만 존재합니다. 교사 쪽에는 아무 데이터도 남지 않아요.

상황 DB 없을 때 Realtime DB 연결 시
학생 점수 확인 ❌ 불가능 ✅ 실시간 확인
누가 풀었는지 확인 ❌ 불가능 ✅ 이름/반 기록
오답 분석 ❌ 불가능 ✅ 문항별 응답 저장
데이터 엑셀 다운로드 ❌ 불가능 ✅ JSON → 엑셀 변환

한 마디로, "채점은 교구가 하고, 기록은 Firebase가 한다"는 구조입니다.

Realtime Database vs Firestore — 뭘 쓰죠?

Firebase에는 데이터베이스가 두 종류 있습니다. 교구용으로는 Realtime Database가 더 적합합니다.

항목 Realtime Database Firestore
구조 JSON 트리 (단순) 컬렉션/문서 (복잡)
코드 난이도 ⚡ 매우 쉬움 보통
실시간 반영 ✅ 즉시 ✅ 즉시
무료 한도 동시 접속 100명, 1GB 읽기 5만/일, 1GB
교구 추천 ✅ 추천 대규모 앱용

결론: 학생 30명이 동시에 퀴즈를 푸는 정도라면 Realtime Database로 충분합니다. 코드도 더 단순하고요.

Step 1. Realtime Database 생성

Firebase Console에서 데이터베이스를 만듭니다. 1분이면 끝납니다.

✅ 따라하기

  1. Firebase Console에서 기존 프로젝트를 선택합니다.
    (이전 글에서 만든 프로젝트가 있다면 그걸 사용하세요)
  2. 좌측 메뉴에서 "빌드(Build)""Realtime Database"를 클릭합니다.
  3. "데이터베이스 만들기" 버튼을 클릭합니다.
  4. 데이터베이스 위치: "미국(us-central1)"을 선택합니다.
    한국 리전이 없으므로 미국이 기본입니다. 교구용으로는 지연 차이를 느끼기 어렵습니다.
  5. 보안 규칙: 일단 "테스트 모드에서 시작"을 선택합니다.
    (나중에 보안 규칙을 수정할 거예요. 지금은 빠르게 동작부터 확인합시다)
  6. "사용 설정"을 클릭하면 데이터베이스가 생성됩니다.

생성이 완료되면 빈 데이터베이스 화면이 나타납니다. 상단에 데이터베이스 URL이 보일 거예요:

https://프로젝트명-default-rtdb.firebaseio.com/

이 URL은 나중에 코드에서 사용합니다. 복사해 두세요.

Step 2. 웹 앱 등록 & 설정 코드 받기

Firebase에 "이 웹사이트에서 데이터베이스를 사용할 거야"라고 등록해야 합니다.

✅ 따라하기

  1. Firebase Console 프로젝트 대시보드에서 톱니바퀴(설정)"프로젝트 설정"으로 이동합니다.
  2. 하단 "내 앱" 섹션에서 웹 아이콘(</>)을 클릭합니다.
    (이미 Hosting에서 앱을 등록했다면 이 단계를 건너뛰세요)
  3. 앱 닉네임: my-quiz-tool 같이 아무 이름이나 입력합니다.
  4. "앱 등록"을 클릭하면 Firebase 설정 코드가 표시됩니다.

화면에 표시되는 설정 코드는 이런 형태입니다:

// Firebase 설정 (이 값들은 프로젝트마다 다릅니다)
const firebaseConfig = {
  apiKey: "AIzaSy...",
  authDomain: "my-project.firebaseapp.com",
  databaseURL: "https://my-project-default-rtdb.firebaseio.com",
  projectId: "my-project",
  storageBucket: "my-project.appspot.com",
  messagingSenderId: "123456789",
  appId: "1:123456789:web:abcdef"
};

⚠️ databaseURL이 핵심입니다
설정 코드 안에 databaseURL 항목이 반드시 있어야 합니다. 없으면 Step 1에서 Realtime Database 생성이 안 된 것이니 다시 확인하세요.

Step 3. HTML 교구에 코드 추가하기

이제 가장 중요한 부분입니다. 기존 HTML 교구 파일에 Firebase 코드를 추가합니다. 딱 두 곳만 수정하면 돼요.

3-1. Firebase SDK 로드 (head 또는 body 끝에 추가)

HTML 파일의 </body> 바로 위에 아래 코드를 붙여넣습니다:

<!-- Firebase SDK (CDN 방식 - 별도 설치 불필요) -->
<script src="https://www.gstatic.com/firebasejs/10.12.0/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/10.12.0/firebase-database-compat.js"></script>

3-2. 초기화 & 데이터 저장 코드

SDK 바로 아래에 초기화 코드를 추가합니다:

<script>
// 1. Firebase 초기화 (아까 복사한 설정 코드를 여기에 붙여넣기)
const firebaseConfig = {
  apiKey: "여기에_본인_apiKey",
  authDomain: "여기에_본인_authDomain",
  databaseURL: "여기에_본인_databaseURL",
  projectId: "여기에_본인_projectId",
  storageBucket: "여기에_본인_storageBucket",
  messagingSenderId: "여기에_본인_senderId",
  appId: "여기에_본인_appId"
};
firebase.initializeApp(firebaseConfig);
const db = firebase.database();

// 2. 퀴즈 결과를 Firebase에 저장하는 함수
function saveQuizResult(studentName, className, score, totalQuestions) {
  db.ref("quiz-results").push({
    name: studentName,
    class: className,
    score: score,
    total: totalQuestions,
    timestamp: new Date().toISOString()
  });
}
</script>

3-3. 저장 함수 호출하기

퀴즈가 끝나는 시점에 saveQuizResult() 함수를 호출하면 됩니다. 예를 들어, "제출" 버튼을 눌렀을 때:

// 제출 버튼 클릭 시 실행되는 기존 함수에 한 줄만 추가
function submitQuiz() {
  const name = document.getElementById("student-name").value;
  const cls = document.getElementById("class-name").value;
  const score = calculateScore(); // 기존 채점 함수

  // ⭐ 이 한 줄이 Firebase에 결과를 저장합니다
  saveQuizResult(name, cls, score, 10);

  alert(`${name}님, ${score}/10점입니다!`);
}

💡 핵심: 기존 교구 코드를 거의 건드릴 필요가 없습니다. Firebase SDK를 로드하고, saveQuizResult() 호출 한 줄만 추가하면 끝이에요.

Step 4. Firebase Console에서 데이터 확인

학생이 퀴즈를 제출하면, Firebase Console에서 즉시 데이터가 나타납니다.

✅ 따라하기

  1. Firebase Console → Realtime Database로 이동합니다.
  2. quiz-results 항목을 클릭하면 저장된 데이터 목록이 보입니다.
  3. 학생이 제출할 때마다 새로고침 없이 실시간으로 데이터가 추가됩니다.

Firebase Console에서 보이는 데이터 구조:

quiz-results/
  ├─ -NxQ1a2b3c4d5e6f
  │   ├─ name: "김민수"
  │   ├─ class: "2학년 3반"
  │   ├─ score: 8
  │   ├─ total: 10
  │   └─ timestamp: "2026-06-22T09:30:15.000Z"
  ├─ -NxQ2f3g4h5i6j7k
  │   ├─ name: "이지은"
  │   ├─ class: "2학년 3반"
  │   ├─ score: 10
  │   ├─ total: 10
  │   └─ timestamp: "2026-06-22T09:31:02.000Z"

JSON 내보내기로 엑셀 변환하기

Firebase Console 우측 상단 ⋮(점 세 개)"JSON 내보내기"를 클릭하면 데이터를 다운로드할 수 있습니다. 다운로드한 JSON 파일은 convertcsv.com 같은 사이트에서 CSV(엑셀)로 변환할 수 있어요.

Step 5. 보안 규칙 설정 (중요!)

테스트 모드로 만든 데이터베이스는 30일 후 자동 만료됩니다. 그 전에 보안 규칙을 설정해야 합니다.

⚠️ 테스트 모드의 위험
테스트 모드에서는 누구나 데이터를 읽고 쓸 수 있습니다. 학생 점수 데이터가 외부에 노출될 수 있으니, 반드시 보안 규칙을 설정하세요.

✅ 따라하기

  1. Firebase Console → Realtime Database → "규칙(Rules)" 탭을 클릭합니다.
  2. 기존 규칙을 지우고 아래 코드를 붙여넣습니다.
  3. "게시" 버튼을 클릭합니다.

추천 보안 규칙 (교구용):

{
  "rules": {
    "quiz-results": {
      ".read": false,        // 외부에서 읽기 차단
      ".write": true         // 학생이 결과를 저장하는 건 허용
    }
  }
}

이 규칙의 의미:

  • .read: false — 외부 사용자가 다른 학생의 데이터를 조회할 수 없습니다.
  • .write: true — 학생이 퀴즈 결과를 저장하는 것은 허용합니다.
  • 교사는 Firebase Console에서 데이터를 직접 확인합니다. (Console은 관리자 권한이라 규칙과 무관)

🔒 더 강화된 규칙이 필요할 때

데이터 검증까지 추가하고 싶다면 이렇게 수정하세요:

{
  "rules": {
    "quiz-results": {
      ".read": false,
      ".write": "newData.hasChildren(['name','class','score','total','timestamp'])
               && newData.child('score').isNumber()
               && newData.child('total').isNumber()"

    }
  }
}

이렇게 하면 필수 필드가 없거나, 점수가 숫자가 아닌 요청은 자동으로 거부됩니다.

실전 예시: 퀴즈 점수 저장 교구

전체 코드를 합친 실전 예시입니다. 복사해서 바로 사용할 수 있습니다.

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>통합사회 퀴즈</title>
</head>
<body>

  <h1>통합사회 1단원 퀴즈</h1>

  <!-- 학생 정보 입력 -->
  <label>이름: <input type="text" id="student-name" placeholder="홍길동"></label>
  <label>반: <input type="text" id="class-name" placeholder="2학년 3반"></label>

  <!-- 퀴즈 문항 (예시 2문항) -->
  <div id="quiz">
    <p>Q1. 인권의 특성 중 '태어나면서부터 가지는 권리'를 뜻하는 것은?</p>
    <label><input type="radio" name="q1" value="a"> 보편성</label>
    <label><input type="radio" name="q1" value="b"> 천부성</label>
    <label><input type="radio" name="q1" value="c"> 불가침성</label>

    <p>Q2. 세계 인권 선언이 채택된 연도는?</p>
    <label><input type="radio" name="q2" value="a"> 1945년</label>
    <label><input type="radio" name="q2" value="b"> 1948년</label>
    <label><input type="radio" name="q2" value="c"> 1950년</label>
  </div>

  <button onclick="submitQuiz()">제출하기</button>
  <p id="result"></p>

  <!-- ✅ Firebase SDK -->
  <script src="https://www.gstatic.com/firebasejs/10.12.0/firebase-app-compat.js"></script>
  <script src="https://www.gstatic.com/firebasejs/10.12.0/firebase-database-compat.js"></script>

  <script>
  // 🔥 Firebase 초기화
  firebase.initializeApp({
    apiKey: "본인_apiKey",
    authDomain: "본인_프로젝트.firebaseapp.com",
    databaseURL: "https://본인_프로젝트-default-rtdb.firebaseio.com",
    projectId: "본인_projectId"
  });
  const db = firebase.database();

  // 정답 목록
  const answers = { q1: "b", q2: "b" };

  function submitQuiz() {
    const name = document.getElementById("student-name").value.trim();
    const cls = document.getElementById("class-name").value.trim();

    if (!name || !cls) {
      alert("이름과 반을 입력해 주세요.");
      return;
    }

    // 채점
    let score = 0;
    for (const [q, ans] of Object.entries(answers)) {
      const selected = document.querySelector(`input[name="${q}"]:checked`);
      if (selected && selected.value === ans) score++;
    }

    // ⭐ Firebase에 결과 저장
    db.ref("quiz-results").push({
      name: name,
      class: cls,
      score: score,
      total: Object.keys(answers).length,
      timestamp: new Date().toISOString()
    }).then(() => {
      document.getElementById("result").textContent =
        `${name}님, ${score}/${Object.keys(answers).length}점입니다! (저장 완료)`;
    });
  }
  </script>
</body>
</html>

이 코드를 복사해서 firebaseConfig 부분만 본인 프로젝트 값으로 바꾸면 바로 동작합니다.

수집된 데이터 활용하기

Firebase Console에서 데이터를 확인하는 것 외에도, JS 코드로 데이터를 읽어와 교사용 대시보드를 만들 수도 있습니다.

교사용: 실시간 응답 현황 보기

// 실시간으로 새 응답이 들어올 때마다 콘솔에 출력
db.ref("quiz-results").on("child_added", (snapshot) => {
  const data = snapshot.val();
  console.log(`${data.name} (${data.class}): ${data.score}/${data.total}점`);
});

// 전체 데이터를 한 번에 가져오기
db.ref("quiz-results").once("value").then((snapshot) => {
  const allResults = snapshot.val();
  console.log(allResults);
});

💡 Tip: 이 코드를 활용하면 교사 전용 페이지에서 학생 응답을 표로 보여주는 대시보드를 만들 수 있습니다. (별도의 HTML 파일로 만들고, 교사만 접속하면 됩니다)

💡 알아두면 좋은 팁

중복 제출 방지하기

학생이 여러 번 제출하는 것을 막고 싶다면, 제출 후 버튼을 비활성화하세요:
document.querySelector("button").disabled = true;
더 확실한 방법은 localStorage에 제출 여부를 기록하는 것입니다.

  • 데이터 초기화: 새 학기나 새 퀴즈를 시작할 때, Firebase Console에서 quiz-results 노드를 삭제하면 깨끗하게 시작할 수 있습니다.
  • 퀴즈별 분류: db.ref("quiz-results/unit1-quiz")처럼 경로를 나누면 퀴즈별로 데이터를 분리할 수 있어요.
  • 무료 한도: Spark Plan 기준 — 동시 접속 100명, 저장 1GB, 다운로드 10GB/월. 학급 단위 퀴즈에는 충분합니다.
  • 오프라인 대응: Firebase Realtime DB는 오프라인에서도 데이터를 캐시합니다. 인터넷이 끊겼다가 복구되면 자동으로 전송돼요.
  • 문항별 응답 저장: push()에 각 문항의 응답도 함께 넣으면 오답 분석이 가능합니다.
    responses: { q1: "b", q2: "a", q3: "c" }

❓ 자주 묻는 질문

Q. Firebase Hosting 없이, CodePen이나 GitHub Pages에서도 되나요?

네, 됩니다. Firebase Realtime Database는 CDN 스크립트 방식이라, 어떤 호스팅에서든 동작합니다. CodePen에서도 Settings → JS에 Firebase SDK URL을 추가하면 바로 사용할 수 있어요.

Q. apiKey가 코드에 노출되는데, 보안 괜찮나요?

Firebase의 apiKey는 "프로젝트 식별자"에 가깝습니다. 비밀번호가 아니에요. 보안은 Realtime Database 규칙에서 관리합니다. 위에서 설정한 규칙(.read: false)이 실제 보안을 담당합니다.

Q. 학생이 개발자 도구로 점수를 조작하면요?

프론트엔드만으로는 100% 방지가 어렵습니다. 하지만 보안 규칙에서 score의 최대값을 제한하거나, 제출 시간을 비교하는 등의 방법으로 비정상 데이터를 걸러낼 수 있습니다. 수행평가 등 엄격한 평가에는 구글 설문지를 병행하세요.

🎯 전체 흐름 정리

Step 1Firebase Console에서 Realtime Database 생성
Step 2웹 앱 등록 & 설정 코드(firebaseConfig) 복사
Step 3HTML 교구에 Firebase SDK + 저장 코드 추가
Step 4Firebase Console에서 데이터 실시간 확인
Step 5보안 규칙 설정 (.read: false / .write: true)

이전 글에서 Firebase Hosting으로 교구를 배포했고, 이번 글에서는 Realtime Database로 학생 응답을 수집하는 방법을 다뤘습니다. 이 두 가지만 조합하면, "내가 만든 퀴즈를 학생에게 배포하고, 결과를 자동으로 수집하는" 완전한 교구가 만들어집니다.

다음 글에서는 Firebase Authentication을 연결해서 구글 로그인으로 학생을 식별하는 방법을 다루겠습니다.

현직 고교 교사가 전하는 통합사회·경제의 정석. 고퀄리티 수업 PPT와 HTML 시뮬레이션 교구, 생생한 여행 기록을 통해 사회를 풀어냅니다.