๐Ÿ”ฅ Firebase Cloud Storage

์ง€์€ยท2023๋…„ 2์›” 1์ผ
1

๐Ÿš‚ ํ† ์ด ํ”„๋กœ์ ํŠธ

๋ชฉ๋ก ๋ณด๊ธฐ
3/10
post-thumbnail

1. ํ”„๋กœ์ ํŠธ์— Cloud Storage ์ถ”๊ฐ€


2. Storage ๋งŒ๋“ค๊ธฐ

import { initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';
import { getFirestore } from 'firebase/firestore';
import { getStorage } from 'firebase/storage'; // import

const firebaseConfig = {
  ...
};

export const firebase = initializeApp(firebaseConfig);
export const auth = getAuth();
export const db = getFirestore(firebase);
export const storage = getStorage(firebase); // storage ์ƒ์„ฑ

์›น์—์„œ Cloud Storage ์‹œ์ž‘ํ•˜๊ธฐ - Firebase


3. Storage์— ์ด๋ฏธ์ง€ ์˜ฌ๋ฆฌ๊ธฐ

  1. ํŒŒ์ผ์„ ์—…๋กœ๋“œ/๋‹ค์šด๋กœ๋“œ, ์‚ญ์ œ, ์—…๋ฐ์ดํŠธ ๋“ฑ์„ ํ•˜๋ ค๋ฉด ๋จผ์ € ์ž‘์—…ํ•˜๋ ค๋Š” ํŒŒ์ผ์— ๋Œ€ํ•œ ์ฐธ์กฐ(๊ฒฝ๋กœ)๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.
  2. uploadString() ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์›์‹œ base64 , base64url ๋˜๋Š” data_url ์ธ์ฝ”๋”ฉ ๋ฌธ์ž์—ด์„ Cloud Storage์— ์—…๋กœ๋“œํ•  ์ˆ˜ ์žˆ๋‹ค.
  3. ์ด๋ ‡๊ฒŒ ์—…๋กœ๋“œํ•œ ํŒŒ์ผ์„ ํ™”๋ฉด์— ๋ณด์—ฌ์ฃผ๋ ค๋ฉด getDownloadURL() ๋ฉ”์†Œ๋“œ๋กœ ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œํ•ด์•ผ ํ•œ๋‹ค.

๐Ÿ“‚ Home.js

import { ref, uploadString, getDownloadURL } from 'firebase/storage';
import { storage } from 'fbase';
import { v4 as uuidv4 } from 'uuid';

const [attachment, setAttachment] = useState(null); // ์ด๋ฏธ์ง€ url

...

const onSubmit = async (e) => {
	e.preventDefault();
	// ํŒŒ์ผ ์ฐธ์กฐ ์ƒ์„ฑ
	const fileRef = ref(storage, `${userObj.email}/${uuidv4()}`); // ์œ ์ € ์ด๋ฉ”์ผ๊ณผ uuid๋กœ ๊ฒฝ๋กœ ์ƒ์„ฑ
	// ํŒŒ์ผ ์—…๋กœ๋“œ
	const response = await uploadString(fileRef, attachment, 'data_url');
	// ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ
	const fileUrl = await getDownloadURL(ref(storage, fileRef));
  
	// ํŠธ์œ— ๊ฐ์ฒด
	const tweetObj = {
		text: tweet,
		createdAt: Date.now(),
		creatorId: userObj.uid,
		fileUrl,
	};

	// ์„œ๋ฒ„์— ์—…๋กœ๋“œ
	try {
		const docRef = await addDoc(collection(db, 'Tweets'), tweetObj);
		console.log('Document written with ID: ', docRef.id);
	} catch (error) {
		console.error('Error adding document: ', error);
	}

	setTweet('');
	setAttachment(null);
};

// File input ํ•ธ๋“ค๋Ÿฌ
const onFileChange = (e) => {
	const {
		target: { files },
	} = e;
	const file = files[0];
	const reader = new FileReader(); // reader ์ƒ์„ฑ

	// reader์— onLoadEnd ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ์ถ”๊ฐ€
	reader.onloadend = (finishedEvent) => {
		// ๋กœ๋”ฉ ์™„๋ฃŒ๋˜๋ฉด ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ
		const {
			currentTarget: { result },
		} = finishedEvent;
		setAttachment(result);
	};
	reader.readAsDataURL(file);
};

const onClearAttachment = () => setAttachment(null);
...

์ฐธ์กฐ ๋งŒ๋“ค๊ธฐ - Firebase
๋ฌธ์ž์—ด์—์„œ ์—…๋กœ๋“œ - Firebase
URL์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ ๋‹ค์šด๋กœ๋“œ - Firebase

Firebase ์ฝ˜์†”์˜ Storage์—์„œ ์œ ์ € ์ด๋ฉ”์ผ์„ ์ด๋ฆ„์œผ๋กœ ์ƒ์„ฑ๋œ ํด๋” ์•ˆ์— ์ด๋ฏธ์ง€๊ฐ€ ์—…๋กœ๋“œ ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

Cloud Firestore์—๋„ fileUrl ์†์„ฑ์— ์ด๋ฏธ์ง€์˜ ๊ฒฝ๋กœ๊ฐ€ ์ž…๋ ฅ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“‚ Tweet.js

...

	<h4>{tweetObj.text}</h4>
	{tweetObj.fileUrl && <img src={tweetObj.fileUrl} width='50px' />}
	{isCreator && (
		<>
			<button onClick={onDeleteClick}>Delete</button>
			<button onClick={toggleEditing}>Edit</button>
		</>
	)}

...


4. Storage์—์„œ ์ด๋ฏธ์ง€ ์‚ญ์ œ

ํŠธ์œ—์„ ์‚ญ์ œํ–ˆ์„ ๋•Œ ํŠธ์œ—๋งŒ ์‚ญ์ œํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ Storage์— ์ €์žฅํ•œ ์ด๋ฏธ์ง€ ํŒŒ์ผ๊นŒ์ง€ ์‚ญ์ œํ•ด์•ผ ํ•œ๋‹ค.
์ด๋ฏธ์ง€๋ฅผ ์‚ญ์ œํ•˜๋ ค๋ฉด ์ด๋ฏธ์ง€๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ๊ฒฝ๋กœ๋ฅผ ์•Œ์•„์•ผ ํ•œ๋‹ค.

๐Ÿ“‚ Tweet.js

import { storage } from 'fbase';
import { ref, deleteObject } from 'firebase/storage';

...

const onDeleteClick = async () => {
	const ok = window.confirm('์ด ํŠธ์œ—์„ ์‚ญ์ œํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?');

	if (ok) {
		try {
			await deleteDoc(newTweetRef); // db์—์„œ ํŠธ์œ— ์‚ญ์ œ
			if (tweetObj.fileUrl) {
				const desertRef = ref(storage, tweetObj.fileUrl); // ์‚ญ์ œํ•  ์ด๋ฏธ์ง€์˜ ref
				await deleteObject(desertRef); // storage์—์„œ ์ด๋ฏธ์ง€ ํŒŒ์ผ ์‚ญ์ œ
			}
		} catch (err) {
			window.alert('ํŠธ์œ—์„ ์‚ญ์ œํ•˜๋Š” ๋ฐ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.');
		}
	}
};

...
profile
๋ธ”๋กœ๊ทธ ์ด์ „ -> https://janechun.tistory.com

0๊ฐœ์˜ ๋Œ“๊ธ€