앱에 모든 데이터를 담을 수 없다. 이유는?
그래서, 앱이 아닌 서버에 데이터를 저장하고, 서버에서 데이터를 가져오고, 변경한다. 서버를 통해 하는
을 제공해 주는 서비스들이 존재한다. 이를 서버리스라고 부르기도 한다. 대표적인 것이 구글에서 제공해주는 파이어베이스이다.
서버 쪽에서 정한 규칙을 API(Application Programming interface)라고 한다. API의 형태(Request)는,
서버가 제공하는 도메인
www.sparta.com/getdata ←- 데이터 조회 API
www.sparta.com/setData ←- 데이터 저장 API
서버가 만들어 놓은 함수
db.ref('/like/').on('value') ←- 데이터 조회 API
db.ref('/like/').set(new_like); <-- 데이터 저장 API
서버에서 주는(Response) 데이터 형식 : JSON (list, dictionary의 복합 구조)
리액트 네이티브에서 주로 데이터를 준비하는 시점은,
useEffect(()=>{
//서버 API 사용
//이 화면에서 사용 할 데이터 준비 등...
},[])
Expo 에서는 현재 위치 데이터를 얻게 해 주는 도구를 제공하고 있다.
이 도구를 사용하기 위해서는 설치해야 한다.
expo install expo-location
MainPage.js
...
import * as Location from "expo-location";
...
useEffect(()=>{
//뒤의 1000 숫자는 1초를 뜻함
//1초 뒤에 실행되는 코드들이 담겨 있는 함수
setTimeout(()=>{
//헤더의 타이틀 변경
navigation.setOptions({
title:'나만의 꿀팁'
})
//꿀팁 데이터로 모두 초기화 준비
let tip = data.tip;
setState(tip)
setCateState(tip)
getLocation()
setReady(false)
},1000)
...
const getLocation = async () => {
//수많은 로직중에 에러가 발생하면
//해당 에러를 포착하여 로직을 멈추고,에러를 해결하기 위한 catch 영역 로직이 실행
try {
//자바스크립트 함수의 실행순서를 고정하기 위해 쓰는 async,await
await Location.requestPermissionsAsync();
const locationData= await Location.getCurrentPositionAsync();
console.log(locationData)
} catch (error) {
//혹시나 위치를 못가져올 경우를 대비해서, 안내를 준비합니다
Alert.alert("위치를 찾을 수가 없습니다.", "앱을 껏다 켜볼까요?");
}
}
...
OpenWeather 에서 제공하는 Weather API를 사용할 것이다.
서버가 제공하는 도메인 형식의 API를 사용하려면, 사용을 위한 도두가 필요하다. 이는 Javascript에서 제공하는 도구로 axios 라고 부른다.
다음과 같이 설치를 진행한다.
yarn add axios
위도, 경도만 알면 날씨 데이터를 건네준다.
API_KEY : API 제공 업체 측에 가입을 한 다음 부여 받은 키 값
MainPage.js
...
import axios from "axios"
...
//날씨 데이터 상태관리 상태 생성!
const [weather, setWeather] = useState({
temp : 0,
condition : ''
})
...
useEffect(()=>{
//뒤의 1000 숫자는 1초를 뜻함
//1초 뒤에 실행되는 코드들이 담겨 있는 함수
setTimeout(()=>{
//헤더의 타이틀 변경
navigation.setOptions({
title:'나만의 꿀팁'
})
//꿀팁 데이터로 모두 초기화 준비
let tip = data.tip;
setState(tip)
setCateState(tip)
getLocation()
setReady(false)
},1000)
},[])
const getLocation = async () => {
//수많은 로직중에 에러가 발생하면
//해당 에러를 포착하여 로직을 멈추고,에러를 해결하기 위한 catch 영역 로직이 실행
try {
//자바스크립트 함수의 실행순서를 고정하기 위해 쓰는 async,await
await Location.requestPermissionsAsync();
const locationData= await Location.getCurrentPositionAsync();
const latitude = locationData['coords']['latitude']
const longitude = locationData['coords']['longitude']
const API_KEY = "*********************************";
const result = await axios.get(
`http://api.openweathermap.org/data/2.5/weather?lat=${latitude}&lon=${longitude}&appid=${API_KEY}&units=metric`
);
const temp = result.data.main.temp;
const condition = result.data.weather[0].main
console.log(temp)
console.log(condition)
//오랜만에 복습해보는 객체 리터럴 방식으로 딕셔너리 구성하기!!
//잘 기억이 안난다면 1주차 강의 6-5를 다시 복습해보세요!
setWeather({
temp,condition
})
} catch (error) {
//혹시나 위치를 못가져올 경우를 대비해서, 안내를 준비합니다
Alert.alert("위치를 찾을 수가 없습니다.", "앱을 껏다 켜볼까요?");
}
}
...
<ScrollView style={styles.container}>
<StatusBar style="black" />
{/* <Text style={styles.title}>나만의 꿀팁</Text> */}
<Text style={styles.weather}>오늘의 날씨: {weather.temp + '°C ' + weather.condition} </Text>
...
파이어베이스를 사용할 수 있게 도와주는 expo 도구를 설치해야 한다.
설치
expo install firebase
설치가 완료되면, firebaseConfig.js 파일을 하나 생성해야 한다. (최상위 위치에 생성) 그리고 파이어베이스에 연결할 코드를 이 파일에 입력하여 저장한다.
firebaseConfig.js
//import * as firebase from 'firebase/app';
import firebase from 'firebase/app';
// 사용할 파이어베이스 서비스 주석을 해제합니다
//import "firebase/auth";
import "firebase/database";
//import "firebase/firestore";
//import "firebase/functions";
import "firebase/storage";
// Initialize Firebase
//파이어베이스 사이트에서 봤던 연결정보를 여기에 가져옵니다
const firebaseConfig = {
apiKey: "**********************************",
authDomain: "sparta.firebaseapp.com",
databaseURL: "https://sparta.asia-southeast1.firebasedatabase.app/",
projectId: "sparta",
storageBucket: "sparta.appspot.com",
messagingSenderId: "62045555555",
appId: "1:620434444448:web:dc48bbrrrrrrrrrrf",
measurementId: "G-G55555555"
};
//사용 방법입니다.
//파이어베이스 연결에 혹시 오류가 있을 경우를 대비한 코드로 알아두면 됩니다.
if (!firebase.apps.length) {
firebase.initializeApp(firebaseConfig);
}
export const firebase_db = firebase.database()
데이터 가져오기 함수는 다음과 같다.
firebase_db.ref('/tip').once('value').then((snapshot) => {
let tip = snapshot.val();
})
MainPage.js
...
import {firebase_db} from "../firebaseConfig"
...
useEffect(()=>{
//헤더의 타이틀 변경
navigation.setOptions({
title:'나만의 꿀팁'
})
firebase_db.ref('/tip').once('value').then((snapshot) => {
console.log("파이어베이스에서 데이터 가져왔습니다!!")
let tip = snapshot.val();
setState(tip)
setCateState(tip)
getLocation()
setReady(false)
});
// setTimeout(()=>{
// let tip = data.tip;
// setState(tip)
// setCateState(tip)
// getLocation()
// setReady(true)
// },500)
},[])
큰 데이터(전체 데이터)가 이동하는 것은 앱 퍼포먼스의 저하 원인이 된다. 그러므로, idx 번호만 넘겨 필요한 데이터만 서버로부터 가져오는 것이 앱 퍼포먼스에 낫다.
Card.js
...
<TouchableOpacity style={styles.card} onPress={() => { navigation.navigate('DetailPage', {idx:content.idx}) }}>
...
DetailPage.js
...
import {firebase_db} from "../firebaseConfig"
// firebase로부터 데이터를 가져오기 위해 연결 과정이 필요. firebaseConfig를 import
...
useEffect(()=>{
console.log(route)
navigation.setOptions({
title:route.params.title,
headerStyle: {
backgroundColor: '#000',
shadowColor: "#000",
},
headerTintColor: "#fff",
})
//넘어온 데이터는 route.params에 들어 있습니다.
const { idx } = route.params;
firebase_db.ref('/tip/'+idx).once('value').then((snapshot) => {
let tip = snapshot.val();
setTip(tip)
});
},[])
...
필요한 데이터 구조
사용자마다 고유한 ID 값으로 데이터를 관리할 수 있도록 해 줌.
도구 설치가 필요하다.
expo install expo-constants
실제 코드가 필요하다.
import Constants from 'expo-constants';
console.log(Constants.installationId)
DetailPage.js,
...
import Constants from 'expo-constants';
export default function DetailPage({navigation,route}) {
let user_idx = Constants.installationId
console.log(user_idx)
... useEffect 는 앞서 수정한 코드 그대로 ...
const like = () => {
// like 방 안에
// 특정 사용자 방안에
// 특정 찜 데이터 아이디 방안에
// 특정 찜 데이터 몽땅 저장!
// 찜 데이터 방 > 사용자 방 > 어떤 찜인지 아이디
const user_id = Constants.installationId;
firebase_db.ref('/like/'+user_id+'/'+ tip.idx).set(tip,function(error){
console.log(error)
Alert.alert("찜 완료!")
});
}
...
<TouchableOpacity style={styles.button} onPress={() => like()}><Text style={styles.buttonText}>팁 찜하기</Text></TouchableOpacity>
...
팁을 저장하는 곳은