const { currentUser } = useSelector((state) => state.user);
const { currentUser: { photoURL, displayName, uid },
} = useSelector((state) => state.user);
currentUser : 리덕스 스토어에 있는 유저(파이어베이스를 통해 로그인한 유저)
useSelector를 통해 리덕스 스토어의 값을 가져옴(photoURL, displayName, uid)
#firebase.config
import { initializeApp } from 'firebase/app';
import 'firebase/auth';
import 'firebase/database';
import 'firebase/storage';
const firebaseConfig = {
apiKey: process.env.REACT_APP_API_KEY,
authDomain: process.env.REACT_APP_AUTHDOMAIN,
projectId: process.env.REACT_APP_PROJECTID,
storageBucket: process.env.REACT_APP_STORAGEBUCKET,
messagingSenderId: process.env.REACT_APP_MESSAGINGSENDERID,
appId: process.env.REACT_APP_APPID,
};
const app = initializeApp(firebaseConfig);
export { app };
#어떤 파일.jsx/tsx
import { app } from '../../../Firebase';
import { getAuth } from 'firebase/auth';
const handleLogout = () => {
const auth = getAuth(app);
auth.signOut();
};
<Dropdown.Item onClick={handleLogout}>로그아웃</Dropdown.Item>
: firebase.config
이전 버전과 다르게 config를 설정해야함
: 어떤 파일.jsx(tsx)
firebase.config에서 export 한 app을 가져옴
=> firebase에 기본 정보가 있기 때문에
getAuth~
=> auth를 설정하기 위해 위에처럼 import해야함
handleLogout
=> auth는 getAuth안에 매개변수로 app을 넣어줘야 함
import React, { useRef } from 'react';
const inputOpenImageRef = useRef();
const handleOpenImageRef = () => {
inputOpenImageRef.current.click();
};
<input
type="file"
accept="image/jpeg, image/png, image/svg"
style={{ display: 'none' }}
ref={inputOpenImageRef}
/>
<Dropdown.Item onClick={handleOpenImageRef}>
프로필 사진 변경
</Dropdown.Item>
type="file"은 파일을 받는 액션.
Input은 style={{ display: 'none' }}을 통해 안 보이게 설정(UI/UX).
Input이 어떤 아이템과 클릭 이벤트로 연결되어야 함.
useRef로 inputOpenImageRef라는 ref를 만들어Input과 연결한다(ref)-getElementById. querySelecter
Dropdown의 아이템을 onClick하면 handleOpenImageRef이 호출됨
handleOpenImageRef는 useRef로 연결된 현재(current) Input을 클릭(click())하면 input이 클릭하도록 함
<input
...중략...
onChange={handleUploadImage}
/>
const handleUploadImage = async (event) => {...}
input으로 파일을 변경하는 행동?이 일어나면,
즉, input의 변화가 onChange되면 handleUploadImage가 호출됨
handleUploadImage 는 firebase에 파일 업로드를 관리함
import {
getStorage,
ref as strRef,
getDownloadURL,
uploadBytesResumable,
} from 'firebase/storage';
import mime from 'mime';
const handleUploadImage = async (event) => {
const file = event.target.files[0];
const metadata = { contentType: mime.getType(file.name) };
const storage = getStorage();
firebase/storage 에서 필요한 기능을 import 함
event : 모든 이벤트를 감시? 체크함
file: files에서 제일 첫번째의 것이 file
metadata: 해당 데이터의 타입
mime 설치
npm install mime
import해서 사용하는게 아니고,
const mime = require('mime');
라고 적혀 있는데, 아래처럼 한다.
import mime from 'mime';
그러면 아래와 같은 에러 발생할 것이다.
can not find module 'path'
const storage = getStorage();
firebase의 storage 를 가지고 온다.
import {
getStorage,
ref as strRef,
getDownloadURL,
uploadBytesResumable,
} from 'firebase/storage';
const {
currentUser: { photoURL, displayName, uid },
} = useSelector((state) => state.user);
let uploadTask = uploadBytesResumable(
strRef(storage, `user_image/${uid}`),
file, metadata
);
firebase storage에 'user_image'라는 폴더 아래, input file로 선택한 파일이 저장된다.
이 파일(file)과 metadata가 저장된다.
uid: firebase로 로그인한 유저정보가 갖는 내용
import { getDatabase, ref, update } from 'firebase/database';
import { useDispatch } from 'react-redux';
import { setPhotoURL } from '../../../redux/reducers/user_reducer';
#getDownloadURL 함수
await getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
console.log('downloadURL', downloadURL);
dispatch(setPhotoURL(downloadURL));
update(ref(getDatabase(), `users/${uid}`), { image: downloadURL });
스토리지에 저장한 이미지의 이미지url을 받아서 내 프로필에 저장하는 로직
downloadURL: 이미지의 url, url을 클릭하면 이미지가 브라우저에서 보임
setPhotoURL(downloadURL): 그 이미지 url(downloadURL)을 리덕스 스토어에 저장하는 함수(setPhotoURL)
update~ : 해당 이미지 url로 firebase storage 변경(update) 하는 것