류림스 공간

[항해99 32일차] 2022.04.07 TIL / (파이어베이스 9버전 스토리지에 이미지 업로드 하기!!!!) 본문

TIL/2022 TIL

[항해99 32일차] 2022.04.07 TIL / (파이어베이스 9버전 스토리지에 이미지 업로드 하기!!!!)

ryurim 2022. 4. 7. 20:46
반응형

📔 오늘 할 일 📔

 

1. 다시 복습 (게시글 가져오는 부분이랑 나머지들 ...)

2. 모던 자바스크립트 읽고 포스팅하기

3. 알고리즘 문제 풀기

4. code책 읽기

 


📖 오늘 배운 개념 📖

 

강의는 파이어베이스 8버전으로 알려주지만, 난 파이어베이스 9버전으로 해보겠다!!

우선 업로드 컴포넌트를 만들어준다.

 

🧸 Upload.js

더보기
import React from "react";

const Upload = (props) => {

    const selectFile =(e)=>{
        console.log(e, "나는 e")
        console.log(e.target, "나는 e.target")
        console.log(e.target.files, "나는 e.target.files")
    }

    return (
        <React.Fragment>
            <input type="file" onChange={selectFile}/>
        </React.Fragment>
    )
}

export default Upload;

🧸 화면에 뿌려지는 업로드 컴포넌트

화면에서 콘솔을 확인해보면 이런 식이다.

파일객체는 배열처럼 되어있는 친구다. 실제 array객체가 아니고, 그냥 파일 리스트라고 한당.

 

🧸 콘솔창

더보기
console.log(e, "나는 e") console.log(e.target, "나는 e.target") console.log(e.target.files, "나는 e.target.files")
console.log(e.target.files, "나는 e.target.files")

 

이 인풋에 Ref를 사용하여 접근한다.

 

🧸 Upload.js

더보기
const fileInput =React.useRef();

const selectFile =(e)=>{
         console.log(fileInput.current.files[0], "나는 파일의 첫번째다")
    }

 return (
        <React.Fragment>
            <input type="file" onChange={selectFile} ref={fileInput}/>
        </React.Fragment>
    )

🧸 다시 콘솔창

더보기
console.log(fileInput.current.files[0], "나는 파일의 첫번째다")

 

잘 접근하는 것을 볼 수 있다. 이것을 파이어 베이스 스토리지에 업로드를 해보려고 한다.

🧸 이 내용을  추가해준다.

더보기
    //임포트 먼저 ^_^
    import { getStorage, ref, uploadBytes } from "firebase/storage";
    
    //버튼 누르면 실행되는 함수
    const uploadFB=()=>{
        let image = fileInput.current.files[0]; //이미지 가져왔으니까 참조를 만들어라 !
        const storage = getStorage();
        const storageRef = ref(storage, `images/${image.name}`);
        console.log("나는스토리지",storage,"나는 스토리지 Ref",storageRef);

        uploadBytes(storageRef, image).then((snapshot) => {
            console.log(snapshot,'이건 스냅샷');
          });
    }
    
   return (
        <React.Fragment>
            <input type="file" onChange={selectFile} ref={fileInput}/>
            <Button text="업로드하기" _onClick={uploadFB}></Button>
        </React.Fragment>
    )

🧸 콘솔창에 찍힌 스냅샷의 모습

더보기
콘솔에 찍힌 스냅샷의 모습 ㅎ

🧸 파이어 베이스 스토리지

더보기
파이어베이스에 들어온 이미지

 

이렇게..!!! 파이어베이스 스토리지에 이미지가 잘 들어온 것을 확인할 수 있다.

이렇게 업로드하면, 게시글에 미리보기 식으로 보여줘야된다.

이미지의 링크를 받아와야되는데 ..이것을 스냅샷 안에서 받아올 수 있다.

 

파이어베이스 9버전으로 URL 링크 받아오기

import { getStorage, ref, uploadBytes,getDownloadURL } from "firebase/storage";

const uploadFB=()=>{
        let image = fileInput.current.files[0]; //이미지 가져왔으니까 참조를 만들어라 !
        const storage = getStorage();
        const storageRef = ref(storage, `images/${image.name}`);
        console.log("나는스토리지",storage,"나는 스토리지 Ref",storageRef);

        uploadBytes(storageRef, image).then((snapshot) => {
            console.log(snapshot,'이건 스냅샷');
            
            getDownloadURL(storageRef).then((url)=>{
                console.log(url,"나는 URL")
            })
          });
    }

에러와의 전쟁 끝에...URL을 불러왔다 ...8버전에서는 getDownloadURL() 이런식으로 쓰던데... 공식문서보고 ㅠㅠ꽤나 애를 먹었당...

나는 URL

이것을 리덕스 모듈로 빼주기 위해 image.js파일을 만들어준다.

어떤 액션이 필요한지 우선 생각한다.

 

1. 이미지를 파이어베이스에 올리고,  리덕스에 이미지 경로를 넣어주는 액션

2. 이미지가 업로드 중일 때 파일 선택을 막아주는 액션(지금은 이미지 업로드 중이야!라고 알려주는 액션)

 

🧸 이미지 리덕스 모듈 코드

더보기
//이미지 리덕스 모듈

import { createAction, handleActions } from "redux-actions";
import produce from "immer";

import { getStorage, ref, uploadBytes,getDownloadURL } from "firebase/storage";

const UPLOADING ="UPLOADING";
const UPLOAD_IMG="UPLOAD_IMG";

const uploading =createAction(UPLOADING, (uploading)=>({uploading}));
const uploadImg =createAction(UPLOADING, (image_url)=>({image_url}));

const initialState={
    image_url:'',
    uploading: false,
};
const uploadingFB =(image)=>{
    return function(dispatch,getState,{history}){
        dispatch(uploading(true));
        const storage = getStorage();
        const storageRef = ref(storage, `images/${image.name}`);
        console.log("나는스토리지",storage,"나는 스토리지 Ref",storageRef);

        uploadBytes(storageRef, image).then((snapshot) => {
            console.log(snapshot,'이건 스냅샷');
            //이미지 업로드 파이어베이스에 업로드 하면 업로딩 끝남
            getDownloadURL(storageRef).then((url)=>{
                console.log(url,"나는 URL");
                dispatch(uploadImg(url));
            })
          });
    };//re
};//up

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);

const actionCreators={
    uploadImg,
    uploadingFB,
}

export {actionCreators};

🧸 아까의 업로드 컴포넌트

더보기
import { useDispatch } from "react-redux";
import { actionCreators as imageActions} from "../redux/modules/image";

 const dispatch =useDispatch();
 
  const uploadFB=()=>{
        let image = fileInput.current.files[0]; //이미지 가져왔으니까 참조를 만들어라 !
        dispatch(imageActions.uploadingFB(image))
    }

임포트 해주고, 아까 업로드 컴포넌트에 이내용으로 수정해준다!!!

 

그러면 액션이 잘 작동하는 것을 확인할 수 있다...

config스토어에도 이미지를 잘 넣어줘야 잘 작동한다!!! 아래내용처럼 ㅎㅎ

🧸 configstore.js

더보기
import { createStore, combineReducers, applyMiddleware, compose } from "redux";
import thunk from "redux-thunk";
import { createBrowserHistory } from "history";
import { connectRouter } from "connected-react-router";

import User from "./modules/user";
import Post from "./modules/post";
import Image  from "./modules/image";

export const history =createBrowserHistory();

const rootReducer = combineReducers({
    user: User,
    post:Post,
    image:Image,
    // comment: Comment,
    router:connectRouter(history),
  });

const middlewares = [thunk.withExtraArgument({history:history})];

// 지금이 어느 환경인 지 알려줘요. (개발환경, 프로덕션(배포)환경 ...)
const env = process.env.NODE_ENV;

// 개발환경에서는 로거라는 걸 하나만 더 
if (env === "development") {
  const { logger } = require("redux-logger");
  middlewares.push(logger);
};
const composeEnhancers =
  typeof window === "object" && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
    ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
        // Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize...
      })
    : compose;

const enhancer = composeEnhancers(applyMiddleware(...middlewares));

let store = (initialStore) => createStore(rootReducer, enhancer);

export default store();

 

 


🤔 해결한 문제 🤔

 

아니야.....

.....하....

블로그에...정리 다해두고 완료버튼만 클릭하면 되는데....

....새로고침 누르는 바람에...다 날라갔다...

.....................

......................하.........

.............울고싶다~~~~~

오류가 났는데..

정확히 어디에서 오류난지 모르겠다.

내일 미니 프젝하면서

개념 다시 다지고..

그래야겠다...

 


😊 주절주저리 😊

 

 나에게는 고비의 시간이 있다. 그 시간은 바로 1시에서 3시사이..

무진장 잠이 많이 온다... 😂 일리 커피 머신아..빨리오려무나...

잠에게 패배했다.

자고 나니까 ㅠㅠ커피머신기 와서 커피 마시면서 하는중이다..이제..잠과의 전쟁에서 난 승리하겠지 ?ㅋㅋ

뭘 적었었는데...?

새로고침하는바람에 다 날라갔다~

에러도 나고...내용도 날라가고...

 

 


📚부족한 부분📚

 

 내가 스스로 코드를 짤 수 있을까?라는 의문이 든다..

리덕스 리듀서 미들웨어 ..는 물론이고, 아직 자바스크립트 문법도 제대로 잘 알지 못하는데,,?

내장배열 함수..쓰는데 아직 많이 부족하다.

그래서 자바스크립트 공부가 필요하다..

 

우선 모던 자바스크립트 부터 읽으면서 개념을 정리하며,,, 지식을 쌓아가야겠다!


내일

 

1. 새로운 주차 시작

2. 미니프젝...파이팅 내일 계획 짠다.

728x90
반응형
Comments