운동을 열심히 했다면 결과도 확인해주는 것이 미더덕이다. 데이터 라우팅부터 저장까지 삽질 헬 구간이였던 운동 결과 스크린의 개발 일지를 끄적여 보자 ^^(험한말)
운동을 종료하면 마주하는 화면이다.
우선 달리기하는 사람에게 중요한 데이터는 몽땅 제공해보려 했다.
이동 경로
저 하찮고 카와이한 파란색 선은 필자가 슈슈슈슉하고 움직여본 경로이다. 이미지로 제공하는 것이 아닌, 맵 컴포넌트를 불러와 폴리 라인이 그려지도록 배열을 넘겨 받은 것이기 때문에 촐싹거리면서 지도를 줌인 줌아웃 할 수 있다.
칼로리와 페이스
칼로리의 경우 개인 신체 스펙에 따라 계산이 달라지지만 나는 유저 데이터에 신체 정보가 없기때문에 통상적으로 사용하는 계산법을 사용하였다.
//칼로리 계산 칼로리 소모 (kcal) ≈ (거리(km) x MET 값) × 3.5
//3.5는 평균 대사율을 나타내는 상수
const calculateCalories = (totalDistance) => {
const distanceInMeters = totalDistance * 1000
const calories = (distanceInMeters * 8.0 * 3.5) / 1000
return calories
}
const calculatePace = (totalDistance, elapsedTime) => {
const [hours, minutes, seconds] = elapsedTime.split(':');
const elapsedTimeInMinutes = parseInt(hours) * 60 + parseInt(minutes) + parseInt(seconds) / 60;
if (elapsedTimeInMinutes <= 0 || totalDistance <= 0) return 'N/A'
const pace = elapsedTimeInMinutes/totalDistance
const minutesPerKm = Math.floor(pace)
const secondsPerKm = Math.floor((pace-minutesPerKm)*60)
return `${minutesPerKm}' ${secondsPerKm}''`
}
스크린 헤더 버튼은 내게 시련을 안겼다. 사람은 누구나 편한 길로 가고싶어 하지 복잡한 곳으로 가고싶어하겠는가. 그래서 처음엔 버튼을 생성해서 absolute와 z-index 꼼수로 버튼 위치를 헤더에 두고 싶었다.
결과적으로 꼼수는 통하지 않았다. 내가 원하는 위치에 체크 버튼을 생성해주기 위해선 아래와 같이 headerRigth 옵션을 통해 만들어 줘야했다.
이 과정에서 삽질한 내용은 아래에서 좀 더 다뤄보도록 하겠다.
오랜만에 서버 코드를 만졌다. 지난번 로그인 기능을 만들었던 기억을 되짚어 코드를 짰다.
우선 데이터베이스 구조는 다음과 같다.
[Records] > test에 저장하기 위해서 userId를 운동 데이터와 엮어 함께 서버로 보냈다.
//fetch
body: JSON.stringify({userId, data})
//save AsyncStorage
saveJsonData('record', {currentDate, data})
여기서 다시 한번 데이터를 JSON 형태로 저장하는 이유를 짚고 넘어가자면 데이터를 활용할 것(가공하거나 검색 등)이 아닌 메모와 같은 부수적인 정보에 가깝기 때문에 이와 같은 형태로 저장하였다.
EndScreen에서 Screens로 데이터 전달하는 방법에 대한 고민
EndScreen.js에서 데이터를 Screens.js로 보내려면 두 컴포넌트 간에 직접적인 연결이 필요하다. 이를 위한 여러가지 방법 중 두가지 방법을 고려하였다.
파라미터를 통해 전달되는 데이터는 일반적으로 한 번만 사용되는 일회성 데이터에 적합하다고 한다. 나 같은 경우 헤더 버튼으로 인해 ConfirmButton 컴포넌트가 별도로 존재하기 때문에 데이터 이동이 EndScreen -> Screen -> ConfirmButton 이루어 진다.
따라서 콜백 함수를 이용하여 데이터를 전달하기로 결정했다.
firbase setDoc과 addDoc의 차이
setDoc과 addDoc은 둘 다 데이터를 추가한다는 점에서 동일한 기능을 한다고 볼 수 있다.
처음엔 필드 값을 날짜로 지정하여 특정 이벤트가 발생한 시간을 효율적으로 확인할 수 있도록 아래처럼 만들었다.
'addDoc' 함수를 사용할 때는 일반적으로 임의 ID가 자동으로 생성되어 사용되기 때문에 내가 원하는데로 개발하기엔 무리가 있었다.
'setDoc' 함수를 사용해보니 데이터가 없을 경우에 추가하고, 있을 경우 데이터를 통째로 업데이트를 적용해버려서 같은 날 여러 데이터가 발생하면 최신 데이터로 덮어씌우는 문제점이 있었다.
나는 동일한 날짜의 데이터 누적을 위해 서브컬렉션을 생성하여 활용하기로 결정하였다. 필드 값을 누적해서 배열로 추가하게 된다면 데이터 양 관리에 어려움이 있을 것으로 생각되었다.
(물론 하루에 달리기 여러번하는 사람 없긴함)
'addDoc' 함수로 서브컬렉션을 사용하면 데이터를 구조화하여 관리하고, 필요한 데이터를 효율적으로 관리할 수 있다.
정리가 잘 된 글이네요. 도움이 됐습니다.