본문 바로가기
공허의 유산/사상의 도구

[Firebase Codelab 샘플] 04. Cloud Firestore에 메세지 쓰기

by 바른생활머시마 2023. 5. 7.
728x90
반응형

앞에서 Firebase SDK를 활용하여 로컬에서 개발 할 환경을 만들었습니다. 꽤 많은 일들을 했죠.

https://learn-and-give.tistory.com/105

 

[Firebase Codelab 샘플] 03. Firebase SDK 설치와 CLI 기반 개발환경 구성

앞에서, 구글 계정 연동과 DB, Storage를 Firebase로 쓸 수 있도록 설정하는 것을 살펴 보았습니다. https://learn-and-give.tistory.com/104 [Firebase Codelab 샘플] 02.구글 로그인과 Cloud Firestore(DB), Cloud Storage 사용

learn-and-give.tistory.com

 

이제 실제 채팅 데이터를 Firebase에 기록하고 읽는 과정을 진행해 보겠습니다.

 

데이터가 저장되는 형식

데이터가 어떤 형식으로 저장되는지 알아보겠습니다. Firebase console을 통해서 Cloud Firestore로 들어가 보면, 저장 된 데이터를 볼 수 있는데, 설명의 순서와 관계 없이 미리 진행 해 본 후 입력 된 결과 데이터를 먼저 보는 것도 이해하는데 도움이 될 것 같습니다. 아래는 Codelab 예제로 구현한 채팅의 입력 데이터가 저장 된 형태입니다.

 

공식 문서는 아래에 있어요.

https://firebase.google.com/docs/firestore/data-model?authuser=0&hl=ko 

 

Cloud Firestore 데이터 모델  |  Firebase

5월 10일, Google I/O에서 Firebase가 돌아옵니다. 지금 등록하기 의견 보내기 Cloud Firestore 데이터 모델 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. Cloud Firestore

firebase.google.com

 

이 예에서 만들게 될 데이터에 대해서 살펴보겠습니다.

처음에 새 프로젝트에서 시작하면 아래와 같이 아무런 데이터가 있지 않습니다.

 

메세지 입출력을 다 구현하고 나면 아래와 같은 형식으로 데이터가 저장 됩니다.

 

폴더 형태와 json 형태로 구성되어 있다고 생각하면 됩니다.

가장 위에 컬렉션이 있고(위 그림의 경우, message, fcmTokens), 컬렉션 하위에 문서가 추가 됩니다. 문서는 이름을 지정 할 수도 있고, 이름을 지정하지 않고 문서를 추가하면 위 그림처럼 임의의 이름을 시스템이 지정 해 줍니다. 중복 문제 등을 고려하면 그냥 자동 생성도 좋은데 뭔가 쿼리 같은 것을 쓸 필요가 있다면 이름을 지정 해 줄 수도 있죠. 문서는 JSON 형태로 필드명과 속성으로 구성 됩니다. 이런 것은 설계 단계에서 미리 정의가 되어야 하는데, 이 예의 경우, 아래와 같은 구조를 가지고 있도록 설계 했다고 합니다. 이런 자료도 살펴보고 향후 자신의 서비스 개발에 참고하여 자신의 서비스 데이터 구조를 이런 형태로 표현 해 보면 도움이 될 것 같습니다.

 

 

 

데이터 저장하기

 

이 정도 개괄적인 내용을 기억하고 다음을 살펴보면 훨씬 이해가 쉽습니다.

이미 대부분의 코드가 다 작성되어 있고, 특정 액션을 취했을 때 실행 할 코드만 작성하면 되도록 준비 된 상태이므로, 메세지 입력을 처리하는 부분의 코드만 입력해주면 됩니다.

index.js

// Saves a new message to Cloud Firestore.
async function saveMessage(messageText) {
  // Add a new message entry to the Firebase database.
  try {
    await addDoc(collection(getFirestore(), 'messages'), {
      name: getUserName(),
      text: messageText,
      profilePicUrl: getProfilePicUrl(),
      timestamp: serverTimestamp()
    });
  }
  catch(error) {
    console.error('Error writing new message to Firebase Database', error);
  }
}

 앞에서 살펴 본 데이터 구조를 상기해 보면, 대충 어떤 식으로 데이터가 추가되는지 이해가 됩니다.

addDoc이라는 API로 데이터를 추가하는데, collection을 추가하며, 대상은 messages라는 collection입니다. 데이터에는 name, text, 프로필 이미지 경로, 그리고 서버측 시간이 저장 됩니다. 이게 끝~~~~

 

 ** 혹시 잘 안되시면, 다른 브라우져로 해보시거나, 브라우져의 캐시를 삭제하고 해보세요~ 저도 이 문제로 한참 삽질했었어요. 코드는 잘 입력했는데 데이터가 입력되지 않았어요.

 

정상적으로 입력 처리가 잘 되면, 테스트 페이지에서 입력 후 바로 Cloud Firestore에 데이터가 추가 되는 것을 볼 수 있습니다.

 

메세지 읽기

메세지를 읽어서 화면에 보여주는 처리를 해보겠습니다.

내가 입력하면 입력한 것을 그냥 바로 보여주면 되는데, 왜 서버로부터 다시 읽어서 보여줘야 하는지는 한번 생각 해 보는 것도 좋을 것 같아요. 대화에 참여한 사람들이 상호 대화 문맥을 공유하고 있어야 되는데, 서버에는 올라가지 않았고 자신만 자신이 입력한 메세지가 추가 된 대화를 보고 있다면 서로 다른 대화 문맥을 가지고 있을 것입니다. 물론, 서버에 올라가기 전 자신의 메세지를 자기에게 빠르게 보여주면 입력이 빠르게 된다는 체감 성능의 향상을 가져 올 수 있을 것입니다. 카톡도 내가 메세지를 입력하면 일단 화면에 전달 된것처럼 보여주는 것 같아요. 전송이 안되면 나중에 전송이 안되었다고 재시도 하거나 삭제 하는 표시를 해주는 것을 보면~

 

아무튼~~~

메세지를 읽어오는 것도, 메세지를 기록하는 것처럼, 가이드에 제공되는 코드를 입력하기만 하면 됩니다.

// Loads chat messages history and listens for upcoming ones.
function loadMessages() {
  // Create the query to load the last 12 messages and listen for new ones.
  const recentMessagesQuery = query(collection(getFirestore(), 'messages'), orderBy('timestamp', 'desc'), limit(12));
  
  // Start listening to the query.
  onSnapshot(recentMessagesQuery, function(snapshot) {
    snapshot.docChanges().forEach(function(change) {
      if (change.type === 'removed') {
        deleteMessage(change.doc.id);
      } else {
        var message = change.doc.data();
        displayMessage(change.doc.id, message.timestamp, message.name,
                      message.text, message.profilePicUrl, message.imageUrl);
      }
    });
  });
}

코드를 좀 살펴보니, 대충 쿼리를 통해서 데이터를 가져온다는 것은 알겠는데, 어떻게 새로운 데이터가 있을 때 이것을 가져오게 되는지는 알 수가 없었는데요, onSnapshot이라는 API가 그런 역할을 해줍니다.

공식 가이드 문서는 아래에 있어요.

https://firebase.google.com/docs/firestore/query-data/listen?hl=ko 

 

Cloud Firestore로 실시간 업데이트 가져오기  |  Firebase

5월 10일, Google I/O에서 Firebase가 돌아옵니다. 지금 등록하기 의견 보내기 Cloud Firestore로 실시간 업데이트 가져오기 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하

firebase.google.com

문서에 있는 정의를 보면,

onSnapshot() 메서드로 문서를 리슨할 수 있습니다. 사용자가 제공하는 콜백이 최초로 호출될 때 단일 문서의 현재 콘텐츠로 문서 스냅샷이 즉시 생성됩니다. 그런 다음 콘텐츠가 변경될 때마다 콜백이 호출되어 문서 스냅샷을 업데이트합니다.

 

쿼리 내용을 보면 최근 12개를 읽어 오는 것이고, 읽어 온 정보를 어떻게 표시 해 주는지에 대해서는 자세한 설명이 없습니다. Firebase와의 I/F에 대한 내용만 구현을 하는 것이고, HTML과 관련 된 내용들은 이미 다 구현되어 있으니, 관심이 있으면 샘플 프로젝트를 살펴보는 것이 좋겠습니다.

 

그런데, 한 가지 궁금한 점은, 이 코드를 언제 실행하느냐 하는 것인데, 제공 된 샘플 프로젝트에서 이 함수를 호출하는 곳을 찾아보면, 페이지 로딩 후 실행되는 코드의 가장 마지막에 실행 되도록 되어 있네요.

...
...
// Events for image upload.
imageButtonElement.addEventListener('click', function (e) {
  e.preventDefault();
  mediaCaptureElement.click();
});
mediaCaptureElement.addEventListener('change', onMediaFileSelected);

console.log("Start Firebase Example");
const firebaseAppConfig = getFirebaseConfig();
initializeApp(firebaseAppConfig);

// TODO: Enable Firebase Performance Monitoring.
getPerformance();

initFirebaseAuth();
loadMessages();

 

결과는 아래와 같이 잘 됩니다.

 

다음에는 텍스트 메세지 외 이미지 파일을 주고 받는 부분을 처리 해 보도록 하겠습니다.

https://learn-and-give.tistory.com/107

 

[Firebase Codelab 샘플] 05. 이미지 메세지와 알림 보내기

앞에서 Firebase에서 제공하는 DB인 Cloud Firestore에 메세지 데이터를 저장하고 읽어와서 기본적인 채팅 기능을 구현하였습니다. https://learn-and-give.tistory.com/106 [Firebase Codelab 샘플] 04. Cloud Firestore에 메

learn-and-give.tistory.com

이미지를 주고 받는 예제는 Cloud Storage의 사용에 대해서 배울 수 있는 예 입니다.

728x90
반응형

댓글