1편에 이어 Firebase 연동을 계속해보자.
왼쪽의 메뉴에서 Firestore Database를 선택한 뒤, 데이터베이스 만들기를 클릭한다.
보안 규칙은 테스트 모드에서 시작을 선택하고 다음을 클릭한다.
마지막으로 Firestore가 저장될 서버의 위치까지 선택하면 데이터베이스 생성이 완료된다.
NoSql의 컬렉션은 RDBMS의 테이블과 유사한 의미를 가지고 있다. 하지만 RDBMS와는 다르게 스키마를 강요하지 않아 다양한 필드 값을 가질 수 있다.
지하철 역에 대한 정보를 저장할 것이기 때문에 이름을 station으로 정했다.
컬렉션의 이름을 입력하고 다음 버튼을 누르면 첫 번째 문서 추가라는 단계로 넘어가게 되는데, 여기서 문서란 RDBMS의 Row를 의미한다.
나중에 지울 수도 있으니, 간단하게 정보를 입력하고 저장을 누르자.
성공적으로 컬렉션과 문서가 생성된 것을 확인할 수 있다.
이제 역 목록을 받아와서 컬렉션에 저장해보자.
다운로드 받은 JSON 파일을 StationInfo라는 이름으로 저장하고, InitStation.js 파일에서 읽어왔다.
// InitStation.js
import StationInfo from "./StationInfo.json";
const InitStation = () => {
return (
<div>
{StationInfo.DATA.map((station) => {
console.log(station);
})}
</div>
);
};
export default InitStation;
// App.js
import InitStation from "./InitStation";
function App() {
<div className="App">
<InitStation/>
</div>
}
여기서 나는 1호선부터 9호선까지의 데이터만 사용할 것이기 때문에 필터링 함수를 구현하여 데이터를 필터링 해주었다.
// 필터링 함수
const filterLine = (line) => {
if (line.length !== 4 || isNaN(parseInt(line.substring(0, 2)))) {
return false;
}
return true;
};
여러 컴포넌트에서 직접 DB에 접근하는 것은 좋지 못하다고 생각해 Firebase.js에서 CRUD의 작업을 수행하는 메소드를 export해서, 다른 컴포넌트에서는 그 메소드를 호출만 하는 것으로 방향을 잡았다.
// Firebase.js
// stations 배열을 DB에 저장하는 메소드
const initStation = async (stations) => {
stations.map(async (station) => {
const stationRef = doc(fireStore, "station", station.station_cd);
await setDoc(stationRef, { ...station, visited: false });
});
};
doc(fireStore, "station", station.station_cd)
의 인자는 각각 fireStore 객체, 컬렉션 명, 문서의 ID를 의미한다.
따라서, fireStore에 존재하는 "station" 컬렉션에 station_cd를 문서의 ID(PK)로 가지도록 데이터를 INSERT 할 것이라는 것을 의미한다.
실제로 데이터를 넣기 위해 InitStation.js와 App.js에도 조금 수정을 해주면 성공적으로 데이터 삽입을 할 수 있다.
// InitStation.js
import StationInfo from "./StationInfo.json";
import { initStation } from "./Firebase";
const filterLine = (line) => {
if (line.length !== 4 || isNaN(parseInt(line.substring(0, 2)))) {
return false;
}
return true;
};
export default async () => {
const result = StationInfo.DATA.filter((station) => {
return filterLine(station.line_num);
});
initStation(result);
};
// App.js
import InitStation from "./InitStation";
function App() {
const handleInitStation = async () => {
const stations = InitStation();
console.log(stations);
};
return (
<div className="App">
<button onClick={handleInitStation}>초기화</button>
</div>
);
}
export default App;