코딩 정보/NextJs
[NextJs] 파이어 베이스를 통해 채팅을 구현해보자
꽁이꽁설꽁돌
2025. 5. 12. 01:43
728x90
반응형
목차
파이어 베이스 가입 및 설정
우리는 일단 테스트를 진행할 것이므로 보안 규칙을 모두 다 접근 가능하게 설정해 주자
규칙 설정 코드
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true;
}
}
}
그 후 아래 프로젝트 설정에서 다음과 같은 코드를 복사해주자
위의 코드를 fire-config.ts 로 파일에 넣어주자
firestore 특징
SQL 데이터베이스와 달리 테이블이나 행이 없으며, 컬렉션으로 정리되는 문서에 데이터를 저장합니다. 그리고 각 문서에는 키-값 쌍이 들어 있습니다.
Cloud Firestore 데이터 모델 | Firebase
이제 MongoDB 호환성을 갖춘 Firestore Enterprise 버전을 사용할 수 있습니다. 자세히 알아보기 의견 보내기 Cloud Firestore 데이터 모델 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장
firebase.google.com
따라서 컬렉션안에서 문서를 만들 수 있습니다. 이때 문서는 직접 추가할 수 있고 형식은 지정해 주지 않아도
코드에 따라 알아서 만들어 집니다. 또한 문서 아이디가 중복될 경우 데이터를 덮어 저장 합니다.
테스트 채팅 구현
실시간 채팅창
'use client';
import React, { useEffect, useState } from 'react';
import { collection, onSnapshot } from 'firebase/firestore';
import db from '../../../../fire-config';
interface Chat {
id: string;
text: string;
}
/**
* @description
* 특정 채팅방의 채팅 목록을 실시간으로 가져옵니다.
*/
function ChatCollection({ roomId }: { roomId: string }) {
const [chatData, setChatData] = useState<Chat[]>([]);
useEffect(() => {
const messagesRef = collection(db, 'chats', roomId, 'messages');
const unsubscribe = onSnapshot(messagesRef, (snapshot) => {
const data = snapshot.docs.map((doc) => ({
id: doc.id,
...(doc.data() as { text: string }),
}));
setChatData(data);
});
return () => unsubscribe();
}, [roomId]);
return (
<div>
{chatData.map((chat) => (
<p key={chat.id}>{chat.text}</p>
))}
</div>
);
}
export default ChatCollection;
채팅 구현
'use client';
import React, { useState } from 'react';
import { addDoc, collection } from 'firebase/firestore';
import db from '../../../../fire-config';
/**
* @description
* 채팅 메시지를 특정 채팅방에 추가하는 입력 컴포넌트입니다.
*/
function ChatInput({ roomId }: { roomId: string }) {
const [message, setMessage] = useState('');
async function onSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
if (!message.trim()) return;
await addDoc(collection(db, 'chats', roomId, 'messages'), {
text: message,
});
setMessage('');
}
return (
<form onSubmit={onSubmit}>
<input
type="text"
value={message}
onChange={(e) => setMessage(e.target.value)}
placeholder="Type your message..."
/>
<button type="submit">전송</button>
</form>
);
}
export default ChatInput;
특정 방 입장
'use client';
import ChatCollection from './chat-collection';
import ChatInput from './chat-input';
export default function ChatTest() {
const roomId = 'userA_userB'; // 실제 유저 ID로 대체
return (
<div>
<h1>Chat Room</h1>
<ChatCollection roomId={roomId} />
<ChatInput roomId={roomId} />
</div>
);
}
반응형