[Firebase] Firebase로 Realtime Chat Application 만들기 [1]

bvelog·2021년 7월 8일
2

code.camp

목록 보기
9/9

팀 프로젝트 진행 중, 원하는 서비스를 구현하기 위해 실시간 채팅 서비스를 구축하게 되었다. 직접 Node.js 서버에 Socket.io를 활용하여 서비스를 구현하는 것이 가장 바람직하겠으나, Socket.io의 방대한 정보량에 GG를 선언하고 Firebase를 사용해 실시간 채팅 서비스를 구현하기로 결정했다. Firebase는 굉장히 공식 문서가 친절하기 때문에, 공식 문서만 읽고도 웬만한 서비스 구축이 가능하다. 프로젝트 용 실전 기능 구현 전, 간단히 테스트 용으로 Slack의 채팅 부분을 클론 코딩해 보려고 한다.

Udemy의 Build a Slack Chat App with React, Redux, and Firebase : Reed Barger 강의를 베이스로 Mock App을 만드는 것이 어떻냐는 추천을 받았는데, 해당 강의는 아쉽게도 React의 클래스형 컴포넌트로 작성이 되어 있다. 마침 클래스형을 함수형으로 바꾸는 연습이 필요했던 때라, 나는 강의를 참고하되 코드는 함수형으로 작성했다.

Firebase Setting: Auth / userDB 설계


기본적인 Firebase 셋팅을 마쳤으면, 이메일/비밀번호를 이용한 로그인/회원가입 방식을 사용하기 위해서 Authentication 메뉴의 이메일/비밀번호를 활성화시켜야 한다.

또한, 채팅을 위해 Realtime Database를 사용할 예정이기 때문에 user에 관련된 DB를 셋업하는 것 역시 필수다. Realtime DB는 JSON 형태로 저장되며, 나는 채팅에 필요한 정보가 유저의 이름과 그 유저의 아바타(프로필 사진)이기 때문에, 두 가지의 정보만 DB에 저장하려고 한다.따라서, 데이터 구조는 아래와 같이 설계했다.

{
  "users": {
    "user.uid(유저 고유 아이디)": {
      "name": 유저 이름,
      "avartar" : 유저 프로필 사진
    },
  }
}
  

Auth를 사용하여 유저 정보 만들기

회원가입 폼에 적힌 정보를 받아 Firebase Auth에 넘겨 주기는 매우 간단하다. 나는 handleSubmit이라는 함수를 작성해, 해당 함수가 실행되면 아래의 코드가 실행되도록 코딩했다.

  const handleSubmit = (event) => {
    event.preventDefault();
    // 중복 클릭 방지를 위해 disable 버튼 활성화
    setLoading(true);
    firebase
      .auth()
      .createUserWithEmailAndPassword(이메일, 패스워드)
      .catch((error) => {
        const errorCode = error.code;
        const errorMessage = error.message;
        console.log(errorCode, ":", errorMessage);
      });
  };


함수가 성공적으로 실행되면, Authentication의 Users에 전달한 정보가 잘 저장된다. 이제 이 정보를 Realtime Database에 넘겨야 한다.

보여질 닉네임과 아바타 설정하기

 const handleSubmit = (event) => {
    event.preventDefault();
    // 중복 클릭 방지를 위해 disable 버튼 활성화
    setLoading(true);
    firebase
      .auth()
      .createUserWithEmailAndPassword(이메일, 패스워드)
      .then((userCredential) => {
        const user = userCredential.user;
        user
          .updateProfile({
            displayName: 유저 설정 닉네임,
            photoURL: 프로필 사진 주소
          })
      .catch((error) => {
        const errorCode = error.code;
        const errorMessage = error.message;
        console.log(errorCode, ":", errorMessage);
      });

firebase.auth().createUserWithEmailandPassword 함수는 이메일과 패스워드밖에 인자로 받지 않기 때문에, 따로 유저에게서 받아온 프로필 사진 정보와 닉네임을 저장해 주기 위해선 추가적인 설정이 필요하다. 해서, userCredential.user로 받아온 정보에 updateProfile 함수를 사용해 내가 원하는 정보를 입력해 주었다.

Realtime Database에 유저 정보 등록

Realtime Database에 동시적으로 정보가 저장되는 것이 아니기 때문에, 회원가입으로 받아온 정보를 DB에 넘겨주는 2차 작업을 해야 한다. 코드의 가독성을 위해, DB에 저장하는 함수는 따로 선언해 주었다.

const database = firebase.database().ref("users/");
// users는 DB의 최상위 노드
const saveUser = (user) => {
  return database.child(user.uid).set({
    name: user.displayName,
    avartar: user.photoURL,
    });
  };
// user로 받아온 값을 user.uid 값인 child 노드를 생성한다. 
// 이후 name / avatar 값을 덮어씌운다.
 const handleSubmit = (event) => {
    event.preventDefault();
    // 중복 클릭 방지를 위해 disable 버튼 활성화
    setLoading(true);
    firebase
      .auth()
      .createUserWithEmailAndPassword(이메일, 패스워드)
      .then((userCredential) => {
        const user = userCredential.user;
        user
          .updateProfile({
            displayName: 유저 설정 닉네임,
            photoURL: 프로필 사진 주소
          })
      // 이후, user의 값을 saveUser에 인자로 넘긴다
      .then(() =>
            saveUser(user).then(() => {
              console.log("User Saved");
            })
          )
          .catch((err) => {
            console.log(err);
          });

함수가 잘 실행이 됐다면, "User Save" 로그가 찍히며 Realtime DB에 잘 저장이 된다.

0개의 댓글