일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- firebase
- 자바스크립트
- CSS
- react
- next Link
- 안드로이드
- javascript
- 파이썬
- NPM
- 최적화
- stdin vs input
- 백준 스택 시간초과 python
- 스택
- k for k
- Python
- 알고리즘
- Android
- 코딩테스트
- typescript
- 백준 스택
- C++
- JS
- kotlin
- 파이어베이스
- TS
- 리액트
- 프론트엔드
- 타입스크립트
- nodejs
- HTML
- Today
- Total
sooleeandtomas
Firebase Storage 사용 : 이미지 저장 본문
1. Firebase FireStore
firebase console > firestore 에서 아주 깔끔한 UI로 DB를 저장할 수 있습니다.
mySQL 을 잠깐 다뤄봤는데 설치부터 계정 연결까지 아주 머리가 아팠거든요.
firebase는 그에 반해 정말 쉽게 DB를 저장할 수 있어서 좋은 것 같습니다.
코드에서 firebase store 사용 설정 firebase.js
import "firebase/firestore";
const firebaseConfig = {
apiKey: "AIzaSyDzso2zaGiat_YYrH0PFi2Y7Grhxf9OXkk",
authDomain: "imgcommunity-46e15.firebaseapp.com",
projectId: "imgcommunity-46e15",
storageBucket: "imgcommunity-46e15.appspot.com",
messagingSenderId: "88009085502",
appId: "1:88009085502:web:b79dd8f4407945f393b76f",
measurementId: "G-SJM3XP072F"
};
firebase.initializeApp(firebaseConfig);
const firestore = firebase.firestore();
export { firestore };
2. redux
GetPost 게시글 가져오기 : setPost
redux코드 firestore.collection([storename]).get()
1. 어떤 DB를 사용할 지 설정
2. DB.get() 함수 요청
const getPostFB = () => {
return function (dispatch, getState, {history}){
const postDB = firestore.collection("post");
postDB.get()
.then(docs=>{
docs.forEach(doc => {
console.log(doc.id, doc.data());
})
})
}
}
3. fb에서 가져온 데이터를 reducer 형식에 맞게 정리하기
4. reducer에 설정해 놓은 initialState 형식대로 [ ] 배열에 담기
5. dispatch로 리듀서 setPost에 보내기
const getPostFB = () => {
return function (dispatch, getState, {history}){
const postDB = firestore.collection("post");
postDB.get()
.then(docs=>{
let post_list = []
docs.forEach(doc => {
let _post = doc.data();
let post = {
id: doc.id,
image_url: _post.image_url,
contents: _post.contents,
comment_cnt : _post.comment_cnt,
insert_dt: _post.insert_dt,
user_info:{
user_name: _post.user_name,
user_profile: _post.user_profile,
user_id: _post.user_id
}
}
post_list.push(post);
})
dispatch(setPost(post_list));
})
}
}
꿀팁! 3번 - fb에서 가져온 데이터를 잘 정리할 때 reduce로 정리하면 코드가 짧아집니다.
const getPostFB = () => {
return function (dispatch, getState, {history}){
const postDB = firestore.collection("post");
postDB.get()
.then(docs=>{
let post_list = []
docs.forEach(doc => {
let _post = doc.data();
let post = Object.keys(_post)
.reduce((acc,cur)=>{
if (cur.indexOf("user_") !== -1){ //user_정보가 있다면
return { ...acc, user_info: { ...acc.user_info, [cur]: _post[cur] } }
}
return {...acc, [cur]: _post[cur]}
}, {id: docs.id, user_info: {}})
post_list.push(post);
})
dispatch(setPost(post_list));
})
}
}
Object.keys(_post) 를 이용하면 { } 객체안의 키값들을 [ ] 배열로 넣어줍니다.
배열을 하나씩 순회하면서 cur : _post[cur] 로 넣어주면 됩니다.
_post[cur] : _post의 키값이 cur 인 value를 반환해줍니다.
addPost 게시글 추가하기 : addPost
1. 어떤 DB를 사용할 지 설정해주기
2. getState()로 현재 user의 정보 가져오기
3. 넘겨받은 contents, moment 정보 가져오기
4. 2번과 3번 합치기
5. DB.add() 함수로 데이터(4번에서 합침)넘겨주기
5-1 . DB가 post를 저장함과 동시에, id값을 부여해줍니다.
6. then (doc) => {
7. redux의 addPost() 함수로 데이터(4번에서 합침) + id 값을 보내주기
8. history.replace("/")
}
const addPostFB = (contents="", ) => {
return function(dispatch, getState, {history}){
const postDB = firestore.collection("post");
const _user = getState().user.user;
const user_info = {
user_name: _user.user_name,
user_id: _user.uid,
user_profile: _user.user_profile
}
const _post = {
...initialPost,
contents,
inser_dt: moment().format("YYYY-MM-DD hh:mm:ss"),
}
//firebase Save Data
postDB.add({...user_info, ..._post})
.then(doc => {
let post = {user_info, ..._post, id: doc.id}
dispatch(addPost(post));
history.replace("/");
}).catch(err => {
console.log("작성 실패했습니다." ,err)
})
}
}
3. Firebase Storage
aws 서비스처럼 이미지도 저장하고, 링크를 받아올 수 있도록 해줍니다. (파이어혜자)
1. firebase.js storage 사용하기 설정
import "firebase/storage";
const firebaseConfig = {
apiKey: "AIzaSyDzso2zaGiat_YYrH0PFi2Y7Grhxf9OXkk",
authDomain: "imgcommunity-46e15.firebaseapp.com",
projectId: "imgcommunity-46e15",
storageBucket: "imgcommunity-46e15.appspot.com",
messagingSenderId: "88009085502",
appId: "1:88009085502:web:b79dd8f4407945f393b76f",
measurementId: "G-SJM3XP072F"
};
firebase.initializeApp(firebaseConfig);
const storage = firebase.storage();
export { storage };
2. input -> 이미지(File) 파이어베이스에 올립니다.
3. firebase에서 url 보내주기
const uploadFB = () => {
let image = inputRef.current.files[0];
dispatch(imageActions.uploadImgFB(image))
}
const uploadImgFB = (img) => {
return function (dispatch, getState, {history}){
dispatch(uploading(true));
const _upload = storage.ref(`images/${img.name}`).put(img);
_upload.then((snapshot)=>{
snapshot.ref.getDownloadURL()
.then((url)=>{
dispatch(uploadImg(url))
console.log(url)
})
}
)
}
}
4. 리덕스에 이미지 경로를 넣어주기
export default handleActions({
[UPLOAD_IMG] : (state, action) => produce(state, (draft) => {
draft.image_url = action.payload.image_url;
draft.uploading = false;
}),
[UPLOADING] : (state, action) => produce(state, (draft) => {
draft.uploading = action.payload.uploading;
}),
}, initialState);
5. uploading 상태로 input 버튼 제어하기
const Upload = props => {
const inputRef = useRef();
const dispatch = useDispatch();
const is_uploading = useSelector(state => state.image.uploading);
const uploadFB = () => {
let image = inputRef.current.files[0];
dispatch(imageActions.uploadImgFB(image))
}
return(
<Fragment>
<input
ref={inputRef}
type="file"
disabled={is_uploading}
/>
<Button
bg="dark"
_onClick={uploadFB}
txt="upload"
/>
</Fragment>
)
};
* data:64를 FB에 보내서 url 얻기
const addPostFB = (contents="", ) => {
return function(dispatch, getState, {history}){
const _image = getState().image.preview;
const _upload = storage.ref(`images/${user_info.user_id}_${new Date().getTime()}`).putString(_image, "data_url");
_upload.then(snapshot => {
snapshot.ref.getDownloadURL().then(url=>{return url})
.then(url => {
//firebase Save Data
postDB.add({...user_info, ..._post, image_url: url})
.then(doc => {
let post = {user_info, ..._post, id: doc.id, image_url: url}
dispatch(addPost(post));
history.replace("/");
dispatch(imageActions.setPreview(null));
}).catch(err => {
console.log("포스트 작성에 실패했습니다.", err)
console.log("포스트 작성에 실패했습니다.", err)
})
}).catch(err => {
window.alert("이미지 업로드에 문제가 있습니다.")
console.log("업로드 문제가 있습니다.", err);
})
})
}
}
* data:64를 FB에 보내서 url 얻은 후에 redux에 저장하기
const addPostFB = (contents="", ) => {
return function(dispatch, getState, {history}){
const postDB = firestore.collection("post");
const _user = getState().user.user;
const user_info = {
user_name: _user.user_name,
user_id: _user.uid,
user_profile: _user.user_profile
}
const _post = {
...initialPost,
contents,
insert_dt: moment().format("YYYY-MM-DD hh:mm:ss"),
}
const _image = getState().image.preview;
const _upload = storage.ref(`images/${user_info.user_id}_${new Date().getTime()}`).putString(_image, "data_url");
_upload.then(snapshot => {
snapshot.ref.getDownloadURL().then(url=>{return url})
.then(url => {
//firebase Save Data
postDB.add({...user_info, ..._post, image_url: url})
.then(doc => {
let post = {user_info, ..._post, id: doc.id, image_url: url}
dispatch(addPost(post));
history.replace("/");
dispatch(imageActions.setPreview(null));
}).catch(err => {
console.log("포스트 작성에 실패했습니다.", err)
console.log("포스트 작성에 실패했습니다.", err)
})
}).catch(err => {
window.alert("이미지 업로드에 문제가 있습니다.")
console.log("업로드 문제가 있습니다.", err);
})
})
}
}
'코딩 공부 노트 > React' 카테고리의 다른 글
Infinity Scroll (Debounce & Throttle 어떤걸 쓰면 좋을까?) (0) | 2021.05.14 |
---|---|
Redux 미들웨어로 saga를 써야 할까? thunk를 써야할까? (0) | 2021.05.14 |
로그인, 회원가입 관리 (JWT, firebase) (0) | 2021.05.13 |
REACT 꿀팁 (0) | 2021.05.12 |
React Native의 pros & cons (0) | 2021.04.20 |