- 이제 이미지 트윗을 업로드 해볼 것이다. 그 전에 Home.js의 아래 부분을 주석처리 해줄 것이다.
트윗만 올리는 기능을 지우고 트윗에 이미지URL을 올리는 식으로 구현방식을 바꿀 것이다.
- 우선 myFirebase.js에 strorage를 추가한다.
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
import { getFirestore } from "firebase/firestore";
import { getStorage } from "firebase/storage";
const firebaseConfig = {
apiKey: process.env.REACT_APP_API_KEY,
authDomain: process.env.REACT_APP_AUTH_DOMAIN,
databaseURL: process.env.REACT_APP_DATABASE_URL,
projectId: process.env.REACT_APP_PROJECT_ID,
storageBucket: process.env.REACT_APP_STORAGE_BUCKET,
messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID,
appId: process.env.REACT_APP_APP_ID,
measurementId: process.env.REACT_APP_MEASUREMENT_ID,
};
const firebaseApp = initializeApp(firebaseConfig);
export const authService = getAuth(firebaseApp);
export const dbService = getFirestore(firebaseApp);
export const storageService = getStorage(firebaseApp);
- 오브젝트를 다운로드 및 업로드 하기 위해 firebase에서 reference를 사용할 것이다.
그리고 특별한 식별자를 랜덤으로 생성하기위해 npm install uuid 를 해준다.
import React, { useEffect, useState } from "react";
import { dbService, storageService } from "myFirebase";
import { addDoc, collection, getDocs, orderBy, query, onSnapshot } from "firebase/firestore";
import {ref, uploadString} from "@firebase/storage";
import { v4 as uuidv4 } from "uuid";
import Tweet from "components/Tweet";
// for Home import
const Home = ({ userObj }) => {
const [tweet, setTweet] = useState("");
const [tweets, setTweets] = useState([]);
const [attachment, setAttachment] = useState();
const getTweets = async () => {
const dbTweets = await getDocs(collection(dbService, "tweets"));
dbTweets.forEach((document) => {
// tweet의 구조
const tweetObject = {
...document.data(),
id: document.id,
};
setTweets((prev) => [tweetObject, ...prev]);
});
}
const onSubmit = async (event) => {
// 아무것도 입력하지 않는 행위 방지
event.preventDefault();
const fileRef = ref(storageService, `${userObj.uid}/${uuidv4()}`)
const response = await uploadString(fileRef, attachment, "data_url");
console.log(response);
/*
// tweets collction에 tweet내용과 작성시간을 담은 Doc을 add
await addDoc(collection(dbService, "tweets"), {
text: tweet,
createdAt: Date.now(),
creatorId: userObj.uid,
});
// add한 이후 tweet을 빈 문자열로 초기화
setTweet("");
*/
};
- 위와같이 작성하였는데 업로드가 되지 않았다. 원인을 찾아보니 Storage에 Rules가 아래와 같이 설정되어 있었다.
- 아래와 같이 바꿔준다.
- 이제 이미지를 업로드하면 아래와 같이 콘솔에 로그가 찍히고
- 스토리지에도 이미지가 업로드 된 것을 볼 수 있다.
폴더는 유저 아이디를 기반으로 생성되어 유저마다 파일을 관리할 수 있게 해준다.
- 이제 이미지 URL을 다운 받아서 트윗과 함께 올려보도록하자.
참고로 Firestore DB도 기간이 만료되어서 권한이 빠진 상태였다 true로 바꿔주자.
const onSubmit = async (event) => {
// 아무것도 입력하지 않는 행위 방지
event.preventDefault();
let attachmentURL ="";
if(attachment !== "") {
// 파일 경로 참조 만들기
const fileRef = ref(storageService, `${userObj.uid}/${uuidv4()}`);
// 스토리지 참조경로로 파일 업로드하기
const response = await uploadString(fileRef, attachment, "data_url");
// 스토리지 참조 경로에 있는 파일의 URL을 다운로드해서 변수에 넣고 업데이트
attachmentURL = await getDownloadURL(fileRef);
}
// tweets collction에 tweet내용과 작성시간을 담은 Doc을 add
const tweetObject = {
text: tweet,
createdAt: Date.now(),
creatorId: userObj.uid,
attachmentURL,
};
await addDoc(collection(dbService, "tweets"), tweetObject);
// add한 이후 tweet을 빈 문자열로 초기화
setTweet("");
// 파일 미리보기 img 비우기
setAttachment("");
};
- 잘 트윗되었다.
- Tweet.js도 수정하여 트윗에도 이미지 URL을 활용하여 이미지가 보일 수 있게 하자.
- 아래와 같이 글이 사진과 함께 게시되었다.
- 아직 이미지 오브젝트까지 삭제하는 기능은 구현되지 않았으므로 삭제 기능을 구현하자.
Tweet.js에서 onDeleteClick을 수정하자.
const onDeleteClick = async() => {
const ok = window.confirm("Are you sure to delete this tweet?");
console.log(ok);
if(ok) {
// delete tweet
const tweetTextRef =doc(dbService, "tweets", `${tweetObj.id}`);
await deleteDoc(tweetTextRef);
// delete attachment
const urlRef = ref(storageService, tweetObj.attachmentURL);
await deleteObject(urlRef);
}
};
- 깔끔하게 삭제된다.
728x90
'Firebase' 카테고리의 다른 글
Firebase를 사용한 트위터 클론 코딩#16(Update Profile) (0) | 2022.08.25 |
---|---|
Firebase를 사용한 트위터 클론 코딩#15(Indexing For Profile) (0) | 2022.08.25 |
Firebase를 사용한 트위터 클론 코딩#13(Preview Images) (0) | 2022.08.13 |
Firebase를 사용한 트위터 클론 코딩#12(Delete & Update) (0) | 2022.07.30 |
Firebase를 사용한 트위터 클론 코딩#11(Realtime Tweets) (0) | 2022.07.21 |