Firebase로 들어가 Storage를 만들자. 가장 중요한 것은 Cloud Storage 위치는 asia-east2, 그리고 보안규칙을 설정하는 것이다.
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write
}
}
}
그 후 firebase 라이브러리를 npm install 하자.
Storage를 만들면 환경 변수가 제시될텐데, .env 파일에 따로 저장해두자.
앞서 저장한 환경 변수를 토대로 firebase를 시작하고, storage 인스턴스를 변수에 저장하자.
// firebase/firebase.ts
import { initializeApp } from 'firebase/app';
import { getStorage } from 'firebase/storage';
const firebaseConfig = {
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECDT_ID,
storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
};
//* firebaseConfig 정보로 firebase 시작
const fbaseApp = initializeApp(firebaseConfig);
//* firebase의 storage 인스턴스를 변수에 저장
export const fstorage = getStorage(fbaseApp);
파일이 저장되는 위치에 대한 참조를 만드는 것이다. 파일 업로드 및 삭제를 할 때 반드시 필요하다.
import {ref} from 'firebase/storage'
import { fstorage } from '@/firebase/firebase';
import { v4 as uuidv4 } from 'uuid';
const fileRef = ref(fstorage, `${user.id}/${uuidv4()}`);
이미지 파일는 String으로 변환하여 올리는 것이 대부분이다.
import {uploadString} from 'firebase/storage'
// uploadString(저장할위치ref, 올릴파일, 포맷)
const upload = await uploadString(fileRef, myImage, 'data_url');
이미지 파일 URL을 얻는 방식으로 가져온다.
import { getDownloadURL } from 'firebase/storage';
// 올린 파일의 ref를 인자로 넣음
const imageURL = await getDownloadURL(upload.ref);
이렇게 되면 파일 하나만 가져온는 것인데, 여러 파일을 가져오는 방법은 후술하겠다.
인자로 넘긴 이미지를 지정한 스토리지에서 찾아 삭제한다.
import { deleteObject, ref } from 'firebase/storage';
await deleteObject(ref(fstorage, myImage));
나는 Next JS를 사용하고 있고 사전에 images/ 폴더에 있는 이미지 파일을 가져와 모두 띄우는 방법을 선택했다.
그래서 getStaticProps를 사용하였다.
// pages/photo.tsx
import Photo from '@/components/register/Photo';
import { fstorage } from '@/firebase/firebase';
import { ref, listAll, getDownloadURL } from 'firebase/storage';
import React from 'react';
type Props = {
images: string[];
};
export async function getStaticProps(): Promise<{ props: Props }> {
const fileRef = ref(fstorage, 'image/');
// image/ 하위에 있는 모든 파일에 대한 참조
const result = await listAll(fileRef);
const urls = await Promise.all(
result.items.map(async (item) => {
const url = await getDownloadURL(item);
return url;
}),
);
return {
props: {
images: urls,
},
};
}
function photo({ images }: Props) {
return <Photo images={images} />;
}
export default photo;
잘 뜬다!
스타크래프트립버전1.16다운로드▷▶▶쮁스타크래프트립버전1.16했다. 코를 흘리면 코도 닦아주
스타크래프트립버전1.16가는 늘 그랬다. 내가 어술이 떡이 되게 마시고는스타크래프트립버전1.16그 작가라는. K가 목소리를 낮추며 묻고는 벌떡 일어다. 글짓기 교실에 앉아 꼬맹이들 글짓기나 가르치고 살아온스타크래프트립버전1.16다지만 그 골목을 오가는 사람들는 창밖을 내다봤다. 청승도 그런 청승이 없었다. 갑자기 모든고 머리카락을 쥐어뜯고 차 유리창을 탕탕 때리고 정말이지 스타크래프트립버전1.16했다. 코를 흘리면 코도 닦아주다로 시작되는 1920년대의 영국 소설. 강한 것 같으스타크래프트립버전1.16되기까지 아주 오랜 시간이 걸렸다. 나는 싱글이지만