👋 개요

오늘 하루 동안 Firebase와 순수 JavaScript(Vanilla JS)를 사용하여 개인정보 처리방침 알림 서비스 ‘WAIA’의 핵심 프로토타입을 처음부터 구축했다. 사용자 인증, 서비스 목록 표시, 팔로우/언팔로우, 개인 대시보드 기능까지 완성하며 서비스의 기본 골격을 마련했다.


📝 오늘 한 일

  • 프로젝트 초기 설정: index.html, style.css, app.js 기본 파일 구조 생성
  • Firebase 연동: Firebase 프로젝트 생성 및 웹 앱 연동 설정 완료
  • 사용자 인증 기능: Firebase Authentication을 이용한 이메일/비밀번호 회원가입, 로그인, 로그아웃 기능 구현
  • 데이터베이스 구축: Firestore에 servicesusers 컬렉션 생성 및 데이터 구조 설계
  • 핵심 기능 구현:
    • 전체 서비스 목록 표시 기능
    • 서비스 팔로우/언팔로우 기능 (arrayUnion, arrayRemove 활용)
    • 팔로우한 서비스만 보여주는 ‘내 대시보드’ 기능
  • UI/UX 개선:
    • 로그인 시 환영 메시지와 로그아웃 버튼 레이아웃 개선
    • 전체 서비스 목록을 상태에 따라 색상이 변하는 반응형 그리드 블록 형태로 변경
  • 개발 편의 기능: 여러 서비스를 쉽게 추가할 수 있는 addServicesBatch() 헬퍼 함수 작성

✨ 주요 작업 내용

팔로우/언팔로우 시스템 구축

사용자가 특정 서비스를 추적할 수 있도록 팔로우 시스템을 구축했다. Firestore의 users 컬렉션에 사용자별 문서를 두고, following 필드에 팔로우하는 서비스의 ID를 배열 형태로 저장했다.

코드 스니펫:

// 팔로우/언팔로우 처리 함수
const handleFollow = async (serviceId, isFollowing) => {
  if (!currentUser.loggedIn) return;
  const userRef = db.collection('users').doc(currentUser.uid);
  try {
    if (isFollowing) {
      // 언팔로우: 배열에서 서비스 ID 제거
      await userRef.update({ following: firebase.firestore.FieldValue.arrayRemove(serviceId) });
      currentUser.following = currentUser.following.filter(id => id !== serviceId);
    } else {
      // 팔로우: 배열에 서비스 ID 추가 (중복 방지)
      await userRef.set({ following: firebase.firestore.FieldValue.arrayUnion(serviceId) }, { merge: true });
      currentUser.following.push(serviceId);
    }
    // UI 즉시 업데이트
    await displayDashboard();
    await displayServices();
  } catch (error) {
    console.error('Follow/Unfollow Error:', error);
  }
};

arrayUnionarrayRemove를 사용해 중복 추가나 존재하지 않는 값 삭제에 대한 걱정 없이 깔끔하게 로직을 구현할 수 있었다.


겪었던 문제 및 해결 과정

문제: 로그인 버튼이 반복적으로 작동하지 않는 문제 발생

시도:

  1. 첫 번째 발생: app.js에 팔로우 기능을 추가하며 전체 코드를 교체했는데, 이 과정에서 loginBtn의 이벤트 리스너에서 성공(then) 처리 로직이 누락되었다. 이로 인해 로그인은 성공해도 화면 변화가 없었다.
  2. 두 번째, 세 번째 발생: 대시보드 기능 추가, UI 개선 등 대규모 코드 수정 시 또다시 같은 실수를 반복했다. 코드를 재구성하며 기존의 완전한 이벤트 리스너 코드를 보존하지 못하고, 주석이나 불완전한 코드로 대체해버리는 문제가 있었다. 심지어 하나의 버튼에 비어있는 리스너와 실제 리스너를 중복으로 등록하는 최악의 상황까지 만들었다.

해결: 문제의 근본 원인이 대규모 코드 블록을 한 번에 교체하면서 발생하는 인간의 실수(Human Error)에 있다고 판단했다. 마지막 시도에서는 수정할 app.js의 전체 코드를 미리 완벽하게 작성하고, 특히 문제가 반복된 이벤트 리스너 섹션에 중복이나 누락이 없는지 여러 번 확인한 후 단 한 번의 교체 작업을 진행했다. 이 방법으로 마침내 로그인 기능을 안정화시킬 수 있었다.


💡 새롭게 배운 점

  • 코드 수정의 범위: 대규모의 코드 블록을 통째로 교체하는 방식은 매우 위험하며, 특히 정상적으로 작동하던 핵심 로직(로그인 등)을 쉽게 망가뜨릴 수 있다는 것을 체감했다. 앞으로는 변경이 필요한 부분만 최소한으로 수정하는 ‘외과수술식’ 접근법을 지향해야겠다.
  • Firestore arrayUnion / arrayRemove: 배열 형태의 데이터를 관리할 때 (특히 ‘좋아요’, ‘팔로우’ 기능) 매우 유용하고 직관적인 방법임을 확인했다. 서버 측에서 원자적으로 처리되어 데이터 정합성을 지키기 용이하다.
  • Flexbox를 이용한 동적 그리드: display: flex, flex-wrap: wrap, flex-basis 속성을 조합하여 간단하게 반응형 그리드 레이아웃을 만들 수 있었다.

🚀 다음 계획

  • 처리방침 자동 불러오기: 각 서비스의 개인정보 처리방침 페이지를 주기적으로 크롤링하여 변경점을 감지하는 백엔드 기능 개발
  • 이메일 알림 기능: 처리방침에서 ‘주의 필요’ 상태가 감지되면 해당 서비스를 팔로우하는 사용자에게 이메일로 알림을 보내는 기능 추가
  • 팔로워 수 트래킹: 각 서비스가 몇 명의 사용자에게 팔로우되고 있는지 집계하는 기능