[firebase] 실시간 데이터베이스에서 자식 데이터에 접근하는 방법

문병곤·2021년 1월 17일
0
post-thumbnail

구글 파이어베이스를 이용해서 데이터를 표로 구현하는 프로젝트(?) 미션(?)을 진행 중이다.

사실 파이어베이스의 실시간 데이터베이스에 접근해 데이터를 받아오는 법은 그리 어렵지는 않다. 파이어베이스가 제공하는 공식 문서의 설명이 아주 친절하기 때문이다.

하지만 공식 문서가 아무리 친절하다 한들 어려움이란 것은 생기기 마련이다. 나도 대부분의 문제를 공식문서를 통해 해결했지만 다소 설명이 애매했던 사항이 있었다.

 mounted () {  
   const db = firebase.database().ref('user').limitToLast(10);
      db.on('child_added', snapshot => {
      snapshot.val();
      })
}

자식 객체에 접근해야할 때.

먼저 내가 가지고 있던 데이터베이스의 구조를 한번 보는 게 이해가 빠를 듯 싶다.

기본적으로 파이어베이스의 구조는 json 형식과 같은 트리 구조다.


데이터베이스 이름ㅡㅜ bbs ㅡ ...
		  ㄴ user ㅜ포스트 아이디1 ㅡ [이메일 등등1]
			  ㅏ포스트 아이드2 ㅡ [이메일 등등2]	
                         .....

이런 식이다. 나는 여기서 user 속의 각 포스트 아이디들이 가지고 있는 '이메일 등등'의 데이터를 가져오기 위해 const db = firebase.database().ref('user'); db.on('value', snapshot => { snapshot.val(); 이러한 코드를 사용했다.

하지만 이렇게 해보니 구해지는 값은 '[포스트 아이디1 : {이메일 등등1}], [포스트 아이디2 : {이메일 등등2}],....'이었다. 만약 이 같은 값이 필요하다면 문제가 없었겠지만 나는 '{이메일 등등1},{이메일 등등2},...' 이러한 값이 필요했기 때문에 낭패였다. 즉 포스트 아이디라는 값은 필요가 없었던 것이다.

이를 해결하기 위해 난 firebase.database().ref('user').child() 등을 사용하려 했지만 이럴 때마다 크롬은 나에게 'child'는 함수가 아니라는 식의 답변만 내놓았다.

그렇게 헤메이다가 동기 분의 도움으로 답을 알게됐다. 답은 on('value')아닌 on('child_added')를 쓰는 것이었다. 나도 답을 찾아 헤메이던 중 공식문서에서 해당 부분을 보긴 했었다. 공식문서에는 'child_added'에 대해 다음과 같이 써놓았다.

항목 목록을 검색하거나 항목 목록에 대한 추가를 수신 대기합니다. 이 이벤트는 기존 하위 항목마다 한 번씩 발생한 후 지정된 경로에 하위 항목이 새로 추가될 때마다 다시 발생합니다. 리스너에는 새 하위 항목의 데이터를 포함하는 스냅샷이 전달됩니다.

문제를 해결한 뒤 읽어보면 이해가 되지만, 한창 저 부분으로 어려움을 겪고 있을 때는 단순히 하위 항목에 새로운 값이 추가되었을 때만 사용하는 인자로만 읽혔다. "리스너에는 하위 항목의 데이터를 포함한 스냅샷이 전달된다."라는 부분을 유심히 봤어야 했다....ㅠ

이후에 관련 내용을 찾아보니 다음과 같았다. 이렇게 정리해보면 참 간단한데 공식문서의 글이 이 부분에선 다소 난해한 느낌이었다.

value : 변경이 가해질 때마다 전체 동기화
child_added : 자식에 변경이 가해질 때 동기화가 진행됨 (최초에 동기화가 되며, 그 이후에 자식이 추가될 때만 *. 변경, 삭제는 x)
child_changed : 자식이 변경 되었을 때
child_removed : 자식이 삭제 되었을 때

데이터 필터링

이밖에도 limitToLast() 메서드도 개인적으로는 도움이 됐다. 이 메서드는 전체 데이터에서 특정 갯수의 데이터만 가져오게 한다. 내가 가지고 있는 데이터가 약 3000개에 달하다 보니 console.log를 사용할 때나 새로고침 등을 사용할 때마다 꽤나 부담스러웠다. 하지만 이 메서드를 사용하게 되면서 비교적 간단한 환경에서 테스트를 진행할 수 있었다.

참고로 limitToLast()는 가장 최근에 만들어진 데이터를 기점으로 특정 갯수의 데이터를 가져오는 메서드이고, limitToLast()는 처음부터 생성된 메서드를 기준으로 데이터를 가져온다. 데이터 필터링 과정에서 유용하게 쓰일 듯 하다.

관련된 공식 문서는 여기다.

0개의 댓글