[Firebase] Realtime Database로부터 데이터 읽고 쓰기 (push, once, snap) (feat. Promise, 비동기)

목표

  1. data에 다음 데이터를 저장한다.
  • nickname : 사용자가 앱 게임 중 사용할 닉네임
  • result : 사용자의 게임 결과 점수
  1. data를 불러와서 배열에 저장하고, 정렬을 수행한다.
  • arr : data를 담을 배열
  • sortArray() : 정렬된 배열을 반환하는 함수
  • 참고 : 아래에서 소개한 코드는 여러 방법 중 하나일 뿐이다.
    같은 기능을 구현하더라도 필요에 따라 유연하게 대응할 수 있다.

JavaScript로 원하는 데이터를 저장하기

사용한 문법은 다음과 같다.

firebase.database().ref('데이터저장소').push({
		key1: value1,
		key2: value2,
        	...
		})
}

프로젝트 코드

// 파이어베이스로 유저의 결과 전송
firebase.database().ref('data').push({
		nickname: userNick,
		result: userScore,
		})
}

위 코드를 실행하면 실행 시점의 userNickuserScore가 Realtime Database에 다음과 같이 저장된다.

JavaScript로 데이터 동적으로 불러오기

문법은 다음과 같다.
once() : 더이상의 데이터 변경이 없다고 가정하고 한번만 메서드를 호출하여 데이터를 불러올 것이다. (한 번만 호출되고 삭제되는 콜백)
snap: 데이터를 정적으로 모두 가져온다.

firebase.database().ref('데이터저장소/')
	.once('value', function (snap) {
	for (var i in snap.val()) {
    	console.log(snap.val()[i])
	}
})

프로젝트 코드 : 불러온 데이터를 Object형태로 하나씩 배열에 담았다.

firebase.database().ref('data/')
	.once('value', function (snap) {
	for (var i in snap.val()) {
		arr.push({ 
        	nick: snap.val()[i].nickname, 
            score: snap.val()[i].result 
            });
	}
})

[참고] 프로미스 활용하기

firebase 데이터를 저장하고 읽는 코드, 그리고 다른 동기 함수를 함께 실행할 때, 실행 순서가 꼬여서 원하지 않는 결과를 얻을 수 있다.
때문에 promise ~ then을 적절히 활용해야 한다.

아래 코드는 프로젝트에 사용한 함수를 간단하게 예제화했다.
목표로 한 결과를 반환하도록 작성했지만 최적화가 필요하다.

// 데이터 로드 함수
function loadData() {
	// 파이어베이스로 유저 결과 전송
	firebase.database().ref('데이터저장소').push({저장할 데이터})
		.then(() => {
			// 데이터 저장이 완료되고 나면, 데이터베이스를 배열에 불러오기
			firebase.database().ref('데이터저장소/').once('value', function (snap) {
				for (var i in snap.val()) {
					arr.push({배열로 넘길 값});
				}
			})
			.then(() => sortArr()); // 전체 데이터를 불러오고 나면, 데이터 정렬 수행
	});
}

위의 코드는 불러온 데이터베이스를 정상적으로 정렬하여 반환하는 코드이다.

위 코드를 아래 코드처럼 실행하면 데이터를 불러오기 전에 정렬(sortArr())함수를 먼저 실행하므로
데이터를 아직 불러오지도 않았는데 정렬을 수행하게 된다.

function loadData() {
	// 파이어베이스로 유저 결과 전송
	firebase.database().ref('데이터저장소').push({저장할 데이터})
    // 파이어베이스 불러오기
	firebase.database().ref('데이터저장소/').once('value', function (snap) {
			for (var i in snap.val()) {
				arr.push({배열로 넘길 값});
				}
			})
   // 동기(sortArr())는 항상 비동기(firebase...)에 우선해 실행되므로
   // 잘못된 결과를 반환한다.
   sortArr());
}

다음 과제

  1. axios, async, await를 공부해서 코드를 최적화해봐야겠다!
  2. 파이어베이스 함수가 익숙하지 않아서 적절하게 사용한 건지 잘 모르겠다. on VS once, snap VS snapshot 등.. 공부하기
    2-1. 프로젝트에서는 데이터 활용하는 부분이 많지 않아서 위처럼 firebase.database()~ 를 모두 작성했지만 필요한 것을 import하는 방법과 const로 선언해서 사용해 재사용성 높게 개선하는 연습이 필요하다.
  3. 이전 게시글에서 다룬 보안 규칙에 대해 고민해보기. 모두 true로 두는 것이 편리하지만 보안에 취약해 언제까지나 이렇게 쓰며 개발할 수는 없다..

좋은 웹페이지 즐겨찾기