์..๋ฒํท์ฃผ์/ํ์ผpath ๋ณต์ฌํด์ ๋ธ๋ผ์ฐ์ ์ฃผ์์ฐฝ์ ๋ถ์ฌ ๋ฃ๊ธฐ ํ๋๋ฐ ์ด๋ฏธ์ง๊ฐ ์๋จ์๋...?
์คํ ๋ฆฌ์ง๊ฐ ๋ณด์ ๊ฐํ๋๊ฑฐ๋ ์๋๋ฉด Rules ๋๋ฌธ์ผ์ง๋..
url์ ๋ค์ด๋ก๋ ํ๋ ค๋ฉด public url์ ๋ค์ด๋ก๋๋ฐ์์ผ ํ๋ค.
Cloud Storage์ Reference์ ๋ํด getDownloadURL()๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ํ์ผ์ ๋ค์ด๋ก๋ URL์ ๊ฐ์ ธ์ฌ ์ ์๋ค.
- ์์
import { getStorage, ref, getDownloadURL } from "firebase/storage"; // const storage = getStorage(); getDownloadURL(ref(storage, 'images/stars.jpg')) .then((url) => { // ์์ getDownloadURL()๋ฅผ ํตํด ๋ฐํ๋๋ 'url'์ 'images/stars.jpg'์ ๋ค์ด๋ก๋ URL์ด๋ค. // // ์ด ํ์ผ์ ์ง์ ๋ค์ด๋ก๋ํ ์ ์๋ค. const xhr = new XMLHttpRequest(); xhr.responseType = 'blob'; xhr.onload = (event) => { const blob = xhr.response; }; xhr.open('GET', url); xhr.send(); // // ๋๋ <img> ์์์ ์ฝ์ ํ ์ ์๋ค. const img = document.getElementById('myimg'); img.setAttribute('src', url); }) .catch((error) => { // ์ค๋ฅ ์ฒ๋ฆฌ๋ catch ๊ตฌ๋ฌธ์ผ๋ก ํ๋ฉด ๋๋ค. });
//
import { ref, uploadString, getDownloadURL } from "@firebase/storage";
//
const onSubmit = async (event) => {
event.preventDefault();
//storage์ ํ์ผ ๋ฐ์ดํฐ๊ฐ ์
๋ก๋๋ ์์น ๊ฐ๋ฆฌํค๋ ๋ ํผ๋ฐ์ค ์์ฑํ๊ธฐ
const fileRef = ref(storageService, `${userObj.uid}/${uuidv4()}`);
//๋ ํผ๋ฐ์ค(fileRef)๊ฐ ๊ฐ๋ฆฌํค๋ ์์น์ ์ฐ์ผ๋ก ๋ฐ์ดํฐ ์
๋ก๋ํ๊ธฐ
//fileRef๊ฐ ๊ฐ๋ฆฌํค๋ ์์น์ attachment์ ๋ค์ด์๋ ์ฒจ๋ถํ์ผ url์ ๋ฃ์ด๋ผ, ํฌ๋งทdata_url
const response = await uploadString(fileRef, attachment, "data_url");
console.log(response);
//๐ฅ response์ ref, ์ฆ ์คํ ๋ฆฌ์ง์ ์
๋ก๋ํ ํ์ผ ์์น์ ์๋ ๊ทธ ํ์ผ์ URL์ ๋ค์ด๋ก๋ํด์
// attachmentUrl ๋ณ์์ ๋ฃ์ด์ฃผ์.
let attachmentUrl;
attachmentUrl = await getDownloadURL(response.ref);
//๐ฅ ๊ทธ๋ฌ๊ณ ๋์ attachmentUrl๋ฅผ ์ฝ์์ ์ฐ์ด๋ณด์!
console.log(attachmentUrl);
//ํธ์ํ๊ธฐ ๋๋ฅด๋ฉด ์๋ก์ด document ์์ฑํ๊ธฐ๋ ํ์ฌ ์ฃผ์์ฒ๋ฆฌ
};
//

์ด์ ๋ค์ด๋ก๋ ๋ฐ์ URL์ ํธ์ํ ๋ ๊ฐ์ด ๋ฃ์ด ์ฃผ์!
์ฃผ์ ํ๋ฌ ๊ณ ๊ณ ์ฑ~!!!
//
import { ref, uploadString, getDownloadURL } from "@firebase/storage";
//
const onSubmit = async (event) => {
event.preventDefault();
//storage์ ํ์ผ ๋ฐ์ดํฐ๊ฐ ์
๋ก๋๋ ์์น ๊ฐ๋ฆฌํค๋ ๋ ํผ๋ฐ์ค ์์ฑํ๊ธฐ
const fileRef = ref(storageService, `${userObj.uid}/${uuidv4()}`);
//๋ ํผ๋ฐ์ค(fileRef)๊ฐ ๊ฐ๋ฆฌํค๋ ์์น์ ์ฐ์ผ๋ก ๋ฐ์ดํฐ ์
๋ก๋ํ๊ธฐ
//fileRef๊ฐ ๊ฐ๋ฆฌํค๋ ์์น์ attachment์ ๋ค์ด์๋ ์ฒจ๋ถํ์ผ url์ ๋ฃ์ด๋ผ, ํฌ๋งทdata_url
const response = await uploadString(fileRef, attachment, "data_url");
console.log(response);
//response์ ref, ์ฆ ์คํ ๋ฆฌ์ง์ ์
๋ก๋ํ ํ์ผ ์์น์ ์๋ ๊ทธ ํ์ผ์ URL์ ๋ค์ด๋ก๋ํด์
//attachmentUrl ๋ณ์์ ๋ฃ์ด์ฃผ์.
let attachmentUrl;
attachmentUrl = await getDownloadURL(response.ref);
//๊ทธ๋ฌ๊ณ ๋์ attachmentUrl๋ฅผ ์ฝ์์ ์ฐ์ด๋ณด์!
console.log(attachmentUrl);
//๐ฅ ํธ์ ์ค๋ธ์ ํธ์ ๋ค์ด๋ก๋ํ attachmentUrl ์ถ๊ฐ
const tweetObj = {
text: tweet, //tweet(value๋ก tweet state ๊ฐ)
createdAt: serverTimestamp(), //Date.now(),๋ก ํด๋ ๋์ง๋ง ์ด์ ์๋๊ฑฐ ํจ ์จ๋ณด์(ํ์์กด ๋๋ถ์3 = ์์ธ๋ก ์ค์ ๋์ด ์์)
creatorId: userObj.uid,
attachmentUrl,
};
//๐ฅ ํธ์ํ๊ธฐ ๋ฒํผ ํด๋ฆญํ๋ฉด tweetObj ํํ๋ก ์๋ก์ด document ์์ฑํ์ฌ tweets ์ฝ๋ ์
์ ๋ฃ๊ธฐ
await addDoc(collection(dbService, "tweets"), tweetObj);
//๐ฅ state ๋น์์ form ๋น์ฐ๊ธฐ
setTweet("");
//๐ฅ ํ์ผ ๋ฏธ๋ฆฌ๋ณด๊ธฐ img src ๋น์์ฃผ๊ธฐ
setAttachment("");
};
์ด๋ฏธ์ง ์ฒจ๋ถํด์ ํธ์ํ๊ธฐ

์คํ ๋ฆฌ์ง์๋ ์ด๋ฏธ์ง ์ ์
๋ก๋๋จ!

ํ์ด์ด์คํ ์ด(db)์๋ ์คํ ๋ฆฌ์ง๋ก ์
๋ก๋๋ ํ์ผ ์์น๋ฅผ ๊ฐ๋ฆฌํค๋ ref๋ฅผ ์ฐธ์กฐํ์ฌ ํ์ผurl์ ๋ค์ด๋ก๋ํ์ฌ attachmentUrl๋ก ์ ๋ค์ด๊ฐ ๊ฒ์ ํ์ธ! attachmentUrl์ ์ ํ url์ ๋ธ๋ผ์ฐ์ ์ฃผ์์ฐฝ์ ์
๋ ฅ ์ ์ฐ๋์ฌ์ง์ด ์ ๋จ๋ ๊ฒ์ ํ์ธํ ์ ์์ ^3^!

์์ด~~ ์ด์ Tweet.js ์ปดํฌ๋ํธ์์ ๋คํ๋จผํธ์ attachmentUrl์ img src์ ๋ฃ์ด์ ํธ์ํ ์ด๋ฏธ์ง ํ๋ฉด์ ๋ณด์ด๊ฒ ํด๋ณด์.
//
<>
<h4>{tweetObj.text}</h4>
{/*๐ฅ ์ด๋ฏธ์ง ์
๋ก๋ ํ์ ๋๋ง ๋ณด์ด๊ฒ*/}
{tweetObj.attachmentUrl && (
<img src={tweetObj.attachmentUrl} alt="image" width="500" />
)}
{/*ํธ์ ์ฃผ์ธ์ธ ๊ฒฝ์ฐ๋ง ์ญ์ /์์ ๋ฒํผ ๋ณด์ด๊ฒ*/}
{isOwner && (
<>
<button onClick={onDeleteClick}>์ญ์ </button>
<button onClick={toggleEditing}>์์ </button>
</>
)}
</>

๋ฐ๋ผ์ const [attachment, setAttachment] = useState(""); ๋ก ๋น๊ฐ์ผ๋ก ๋น์๋๋๊ฒ์ ๋ํดํธ๋ก ํ์.
์๋ ์ฝ๋๋ณด๋ฉฐ ๋ฐ๋ผ๊ฐ๊ธธ ์ถ์ฒ..!
//getDownloadURL ์ํฌํธ
import { ref, uploadString, getDownloadURL } from "@firebase/storage";
//์ฌ์ง ์ฒจ๋ถ ์์ด ํ
์คํธ๋ง ํธ์ํ๊ณ ์ถ์ ๋๋ ์์ผ๋ฏ๋ก ๊ธฐ๋ณธ ๊ฐ์ ""๋ก ํด์ผํ๋ค.
//ํธ์ํ ๋ ํ
์คํธ๋ง ์
๋ ฅ์ ์ด๋ฏธ์ง url ""๋ก ๋น์๋๊ธฐ ์ํจ
const [attachment, setAttachment] = useState("");
const onSubmit = async (event) => {
event.preventDefault();
let attachmentUrl = "";
//์ด๋ฏธ์ง ์ฒจ๋ถํ์ง ์๊ณ ํ
์คํธ๋ง ์ฌ๋ฆฌ๊ณ ์ถ์ ๋๋ ์๊ธฐ ๋๋ฌธ์ attachment๊ฐ ์์๋๋ง ์๋ ์ฝ๋ ์คํ
//์ด๋ฏธ์ง ์ฒจ๋ถํ์ง ์์ ๊ฒฝ์ฐ์ attachmentUrl=""์ด ๋๋ค.
if (attachment !== "") {
//ํ์ผ ๊ฒฝ๋ก ์ฐธ์กฐ ๋ง๋ค๊ธฐ
const attachmentRef = ref(storageService, `${userObj.uid}/${uuidv4()}`);
//storage ์ฐธ์กฐ ๊ฒฝ๋ก๋ก ํ์ผ ์
๋ก๋ ํ๊ธฐ
const response = await uploadString(attachmentRef, attachment, "data_url");
//storage ์ฐธ์กฐ ๊ฒฝ๋ก์ ์๋ ํ์ผ์ URL์ ๋ค์ด๋ก๋ํด์ attachmentUrl ๋ณ์์ ๋ฃ์ด์ ์
๋ฐ์ดํธ
attachmentUrl = await getDownloadURL(response.ref);
}
//ํธ์ ์ค๋ธ์ ํธ
const tweetObj = {
text: tweet,
createdAt: Date.now(),
creatorId: userObj.uid,
attachmentUrl,
};
//ํธ์ํ๊ธฐ ๋๋ฅด๋ฉด tweetObj ํํ๋ก ์๋ก์ด document ์์ฑํ์ฌ nweets ์ฝ๋ ์
์ ๋ฃ๊ธฐ
await addDoc(collection(dbService, "tweets"), tweetObj);
//state ๋น์์ form ๋น์ฐ๊ธฐ
setTweet("");
//ํ์ผ ๋ฏธ๋ฆฌ๋ณด๊ธฐ img src ๋น์์ฃผ๊ธฐ
setAttachment("");
};
//์ฒจ๋ถ ํ์ผ url ๋ฃ๋ state์ธ attachment ๋น์์ ํ๋ฆฌ๋ทฐ img src ์์ ๊ธฐ
const onClearAttachment = () => {
//null์์ ๋น ๊ฐ("")์ผ๋ก ์์ , ํธ์ํ ๋ ํ
์คํธ๋ง ์
๋ ฅ์ ์ด๋ฏธ์ง url ""๋ก ๋น์๋๊ธฐ ์ํจ
setAttachment("");
};