[미니프로젝트] 파이어베이스를 이용한 댓글 기능 샘플 제작
🚀 JS 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// Firebase SDK 라이브러리 가져오기
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-app.js";
import {
getFirestore,
collection,
doc,
addDoc,
query,
where,
orderBy,
getDocs,
setDoc,
serverTimestamp,
} from "https://www.gstatic.com/firebasejs/9.22.0/firebase-firestore.js";
// Firebase 구성 정보 설정
const firebaseConfig = {
...
};
// Firebase 인스턴스 초기화
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
// 파라미터 가져오기
// 현재는 임시로 파라미터로 처리
// 추후 개인 게시물의 키값으로 변경예정
function getQueryParam(key) {
const params = new URLSearchParams(window.location.search);
return params.get(key);
}
const key = getQueryParam('key');
const targetId = key || "main";
console.log("targetId: ", targetId);
// 댓글 등록
export async function registerComment(commentText) {
const docData = {
targetId,
comment: commentText,
createdAt: serverTimestamp()
};
const docRef = await addDoc(collection(db, "comments"), docData);
// 생성된 문서 ID
const newId = docRef.id;
// ID 필드 추가
await setDoc(doc(db, "comments", newId), {
id: newId,
...docData
})
}
// 댓글 가져오기
export async function loadComments(callback) {
const q = query(
collection(db, "comments"),
where("targetId", "==", targetId),
orderBy("createdAt", "asc")
);
const querySnapshot = await getDocs(q);
querySnapshot.forEach(doc => {
callback(doc.data());
});
}
// Input Enter Event
$('#commentInput').keypress(function (e) {
if (e.which === 13) { // 13은 Enter 키 코드
e.preventDefault();
$('#commentButton').click();
}
});
🚀 HTML 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<head>
<script type="module">
import { registerComment, loadComments } from '../js/comments.js';
const $commentList = $('#commentList');
const $commentButton = $('#commentButton');
// 등록 버튼
$commentButton.click(async function () {
const comment = $('#commentInput').val();
await registerComment(comment);
window.location.reload();
});
// 댓글 가져오기
if ($commentList.length > 0) {
$commentList.empty();
await loadComments((row) => {
const id = row.id || "";
const comment = row.comment;
const tempHtml = `<li data-id="${id}">${comment}</li>`;
$commentList.append(tempHtml);
});
// 댓글의 스크롤 위치를 최하단으로 이동
$commentList.scrollTop($commentList.prop("scrollHeight"))
}
</script>
</head>
<body>
<!-- 샘플이기에 일단 키 값은 URL 쿼리 파라미터로 대체 -->
<a href="?key=">메인</a>
<a href="?key=A">A</a>
<a href="?key=B">B</a>
<ul id="commentList">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<div id="commentInputGroup">
<input type="text" name="" id="commentInput" placeholder="댓글을 입력해주세요.">
<button type="button" id="commentButton"><img src="../images/icon_send.svg"></button>
</div>
</body>
🚀 CSS 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#commentList {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
align-items: flex-end;
max-height: 400px;
overflow: auto;
}
#commentList > li {
position: relative;
width: max-content;
padding: 5px 15px;
margin: 5px 10px 5px 0;
background-color: #e5e5e5;
border-radius: 12px;
font-size: 16px;
line-height: 24px;
}
#commentList > li::before {
content: "";
position: absolute;
right: 0;
bottom: 2px;
transform: translateX(50%) rotate(10deg);
width: auto;
height: auto;
/* background-color: red; */
border: 10px solid transparent;
border-left-color: #e5e5e5;
border-right: 0;
border-bottom: 0;
box-sizing: border-box;
}
#commentInputGroup {
display: flex;
padding: 0 10px;
margin: 10px 0;
border: 1px solid #dedede;
border-radius: 1000px;
}
#commentInput {
border: 0;
background: none;
outline: none;
width: 100%;
height: 40px;
padding: 0 10px;
font-size: 16px;
}
#commentButton {
flex-shrink: 0;
border: 0;
background: none;
padding: 0;
margin: 0;
width: 40px;
height: 40px;
cursor: pointer;
}
#commentButton img {
width: 50%;
height: 50%;
object-fit: contain;
}
🚀 Firebase 구조
content: 댓글의 내용createdAt: 등록일자id: 댓글의 유니크키 값targetId: 댓글이 출력될 대상의 유니크키 값
🚀 결과
B 링크를 눌렀을 때 출력되는 댓글들