오늘은 역할 배분을 마치고 나니 프로젝트가 빠르게 진전되었다. 내가 맡은 부분은 로그인/회원가입 기능인데, 사실 Firebase에 id와 password만 저장해놓는 것이다. 아이디 중복 체크 부분이 있긴 하지만 그냥 아주아주 간단한 로그인이라고 보면 될 것 이다. 내가 오늘 겪은 시행착오를 기록해가며 프로젝트를 진행하였다.
동적으로 움직이는 페이지를 따와서 로그인 페이지를 만들어보려 했는데, 화면이 예상한대로 움직이지 않았다. 따라서 다음과 같은 시도를 했다.
onclick="toggle()"
속성이 제대로 설정되어 있는지 확인id="container"
가 올바르게 설정되어 있는지 확인if (container) {
console.log('Container found:', container);
} else {
console.error('Container not found!');
}
Uncaught TypeError: Cannot read properties of null (reading 'classList')
라는 에러가 출력되었다. 해당 에러는 container
변수가 null
이기 때문에 발생하는 에러이다. 이 문제는 JavaScript가 실행되는 시점에 HTML 요소를 찾을 수 없기 때문에 발생한다고 한다.다음과 같이 DOMContentLoaded 이벤트를 사용해 html이 완전히 로드된 후 JavaScript가 실행되도록 하여 해결했다. 찾아보니 DOMContentLoaded 이벤트는 브라우저가 HTML 문서의 구조(DOM)를 완전히 로드했을 때 실행되는 이벤트였다.
document.addEventListener('DOMContentLoaded', () => {
let container = document.getElementById('container');
if (container) {
console.log('Container found:', container);
} else {
console.error('Container not found!');
return; // container가 없으면 나머지 코드 실행 방지
}
toggle = () => {
container.classList.toggle('sign-in');
container.classList.toggle('sign-up');
};
setTimeout(() => {
container.classList.add('sign-in');
}, 200);
});
이 문제를 해결하는 과정에서 브라우저는 다음과 같이 동작한다는 것을 알게되었다.
<script>
태그가 있다면 DOM을 완성하기 전에 JavaScript를 실행한다.따라서 만약 HTML이 완전히 로드되기 전에 JavaScript에서 DOM요소 (ex. document.getElementById('container')
)를 찾으려고 하면, 브라우저는 해당 요소를 아직 생성하지 않았기 때문에 null
을 반환한다. 이를 해결하기 위해 DOMContentLoaded
이벤트가 발생한 이후에 JavaScript가 실행되도록 해서 DOM 요소를 안전하게 참조할 수 있다.
회원가입 시 이미 Firebase db에 있는 아이디를 입력하면 "이미 존재하는 ID입니다. 다른 ID를 사용해주세요.” 라는 알림이 뜨도록 하는 기능을 구현 중, ncaught (in promise) ReferenceError: query is not defined at HTMLButtonElement.<anonymous> (login.js:44:17)
와 같은 에러가 발생했다.
아이디와 비밀번호를 모두 입력한 후 버튼을 누르면 try문안에서 회원가입을 시도하기 전에 다음고 같이 중복 ID 체크를 하고 넘어가도록 했다.
// 중복 ID 체크
const memberCollection = collection(db, "members");
onst q = query(memberCollection, where("id", "==", id));
const querySnapshot = await getDocs(q);
if (!querySnapshot.empty) {
alert("이미 존재하는 ID입니다. 다른 ID를 사용해주세요.");
return;
}
위치를 이리저리 바꿔보다가, 해당 오류 메시지를 검색해보니 query 객체를 정의하지 않았거나, 올바르게 가져오지 않은 경우 발생한다고 했다. 따라서 Firestore에서 query를 사용하려면 Firestore SDK에서 올바르게 가져와야 하는 것이다.
해결방법은 정말 간단했다. 바보같지만(…) 관련 함수를 가져오지 않고 그냥 사용하려고 해서 오류가 난 것이다. 다음과 같이 query, where을 모두 가져오니 해결되었다. 꼭 import가 잘 되어있는지 확인 후 사용하자!
import {
getFirestore,
collection,
addDoc,
query,
where,
getDocs
} from "https://www.gstatic.com/firebasejs/9.22.0/firebase-firestore.js";
JavaScript에서 Firebase를 사용하는 것은 익숙하지 않았지만 회원가입/로그인 기능을 구현하면서 조금 익숙해질 수 있었다.
중복 ID를 체크하는 로직을 다시 한 번 정리하면 다음과 같다.
members
라는 컬렉션을 참조해 데이터베이스 내에서 검색할 준비를 한다.getDocs
함수로 실제 데이터를 가져와, 쿼리 결과가 비어 있는지 확인한다.(getDocs
함수는 query를 전달하면 조건에 맞는 데이터만 가져온다.)확실히 오래 앉아있었던만큼 많은 걸 한 것 같다. 나중에는 9시 넘어서까지 할 것 같은데 지금은 9시가 되면 상당히 졸린 상태여서 가능할지..? 자바 강의를 들어야하는데 프로젝트에 집중하다보니 끝나고 진이 빠져서 강의 들을 힘이 잘 안난다🫠 크리스마스에 잘 쉬고 좀 더 체력을 길러보자.