CRUD - 반응 및 Google Firebase

안녕하세요, 다시 나입니다.
이 게시물에서는 Google Firebase에서 파일을 관리하거나 CRUD하는 방법(React를 사용한 저장소)을 공유합니다.

nextjs 프레임워크로 반응 앱 만들기



create-next-app nextjs-crud-gg --ts


라이브러리 설치



npm i -s firebase uuid && npm i --dev @types/uuid


프로젝트 구조 생성.


  • libs 폴더의 storage.ts - (root_project)/libs/storage.ts
  • utils 폴더의 fileManage.ts - (root_project)/utils/fileManage.ts
  • next.config.js에 env 변수 추가
  • index.tsx 페이지 사용자 정의 - 한 페이지만 사용하여 파일을 데모 페이지로 CRUD합니다.

  • I. storage.ts에서 Google Firebase 저장소 설정



    import { initializeApp } from 'firebase/app';
    import { getStorage } from 'firebase/storage';
    
    const firebaseConfig = {
      apiKey: process.env.GOOGLE_API_KEY,
      authDomain: process.env.GOOGLE_AUTH_DOMAIN,
      projectId: process.env.GOOGLE_PROJECT_ID,
      storageBucket: process.env.GOOGLE_STORAGE_BUCKET,
      messagingSenderId: process.env.MESSAGING_SENDER_ID,
      appId: process.env.GOOGLE_APP_ID,
      measurementId: process.env.GOOGLE_MEASUREMENT_ID,
    };
    
    // Initialize Firebase
    const app = initializeApp(firebaseConfig);
    const storage = getStorage(app);
    
    export { storage };
    

    II. next.config.js에서 환경 변수 설정



    /** @type {import('next').NextConfig} */
    
    const nextConfig = {
      reactStrictMode: true,
      swcMinify: true,
      env: {
        GOOGLE_API_KEY: <value_here>,
        GOOGLE_AUTH_DOMAIN:  <value_here>,
        GOOGLE_PROJECT_ID: <value_here>,
        GOOGLE_STORAGE_BUCKET: <value_here>,
        MESSAGING_SENDER_ID: <value_here>,
        GOOGLE_APP_ID:  <value_here>,
        GOOGLE_MEASUREMENT_ID:  <value_here>,
      },
    };
    module.exports = nextConfig;
    

    . 이 링크firebase.google.com를 참조하십시오.

    III. fileManage.ts에서 파일을 관리할 라이브러리를 만듭니다.



    import { storage } from '../libs/storage';
    import {
      deleteObject,
      getDownloadURL,
      listAll,
      ref,
      uploadBytes,
      UploadResult,
    } from 'firebase/storage';
    import { v4 } from 'uuid';
    
    /**
     * Get all file by folder name.
     *
     * @param string folder image.
     * @returns array File of url.
     */
    export async function getAllFile(folder: string) {
      const filesRef = ref(storage, `${folder}`);
      const files = (await listAll(filesRef)).items;
      return Promise.all(
        files.map(async (fileRef) => {
          return await getDownloadURL(fileRef);
        }),
      );
    }
    
    /**
     * Get file by url.
     *
     * @param string url image.
     * @returns boolean true if deleted file.
     */
    export async function getFile(url: string) {
      const fileRef = ref(storage, url);
      return await getDownloadURL(fileRef);
    }
    
    /**
     * Delete file by url.
     *
     * @param string url image.
     * @returns boolean true if deleted file.
     */
    export async function deleteFile(url: string) {
      const fileRef = ref(storage, url);
      await deleteObject(fileRef);
    }
    
    /**
     * Upload file to google firebase storage.
     *
     * @param string folder name.
     * @param array filesUpload list of file
     * @returns array list of url file.
     */
    export async function uploadFile(folder: string, filesUpload: File[]) {
      return Promise.all(
        [...filesUpload].map(async (file: File) => {
          const fileRef = ref(storage, `${folder}/${file.name + v4()}`);
          const value: UploadResult = await uploadBytes(fileRef, file);
          return await getDownloadURL(value.ref);
        }),
      );
    }
    



    방법
    설명


    getAllFile
    Google firebase 저장소의 모든 파일을 fodler 이름으로 가져옵니다.

    getFile
    파일의 URL을 기반으로 단일 파일 가져오기

    삭제파일
    파일의 URL을 기반으로 파일 삭제

    업로드파일
    여러 파일 업로드

    업데이트파일
    새 파일을 업로드하기 전에 업로드한 파일을 삭제할 수 있습니다. 쉽고 간단하게 만듭니다. "deleteFile"+ "uploadFile"방법을 사용할 수 있습니다.

    VI. React로 파일 관리



    I will edit the index.tsx page



    import type { NextPage } from 'next';
    import { useRef, useState } from 'react';
    import { deleteFile, getAllFile, uploadFile } from '../utils/fileManager';
    
    const Home: NextPage = () => {
      // Hook for upload the file
      const [images, setImages] = useState<File[]>([]);
      // Hook for preview the file uploaded.
      const [imagesUploaded, setImageUploaded] = useState<string[]>([]);
      // Hook for list all the file in the "images" folder.
      const [imageGallery, setImageGallery] = useState<string[]>([]);
      // Use fileRef to clean the file after uploaded.
      const fileRef = useRef<HTMLInputElement>(null);
      // Creating the folder in google firebase storage. I named the "images" for contain only the type of image.
      const FOLDER_NAME = 'images';
    
      /**
       * Add file uploaded
       * @param e Event HTML Input Change
       */
      const handleOnChange = (e: any) => {
        setImages(e.target.files as File[]);
        e.target.files = null;
      };
    
      /**
       * Delete the file with url file.
       * @param url string
       */
      const handleOnDelete = (url: string) => {
        deleteFile(url).then(() => {
          setImageUploaded((prev) => prev.filter((img) => img !== url));
          setImageGallery((prev) => prev.filter((img) => img !== url));
          alert(`Deleted file`);
        });
      };
    
      /**
       * Upload file, and show alert if success.
       */
      const handleOnUpload = () => {
        if (images.length === 0) return false;
        uploadFile(FOLDER_NAME, images).then((imageList) => {
          setImageUploaded(imageList);
          alert('Upload file successed');
          if (fileRef.current) {
            fileRef.current.value = '';
          }
        });
      };
    
      /**
       * Get all the files base on the folder name.
       */
      const handleGetFiles = () => {
        getAllFile(FOLDER_NAME)
          .then((listImages) => {
            setImageGallery(listImages);
          })
          .catch((err) => {
            console.log('Something went wrong', err);
          });
      };
    
      return (
        <div className="app">
          <div className="form-control">
            <label htmlFor="file">
              <input
                type="file"
                ref={fileRef}
                onChange={handleOnChange}
                multiple
              />
            </label>
            <button
              className="button"
              onClick={handleOnUpload}
            >
              Upload file to firebase storage
            </button>
          </div>
          <div className="image-container">
            <p>Image preview</p>
            <ul className="image-container__list">
              {imagesUploaded.length > 0 &&
                imagesUploaded.map((image) => (
                  <li
                    style={{ listStyle: 'none' }}
                    key={image}
                  >
                    <img
                      src={image}
                      width="100%"
                    />
                    <button
                      type="button"
                      onClick={() => handleOnDelete(image)}
                    >
                      Delete file
                    </button>
                  </li>
                ))}
            </ul>
          </div>
          <div className="image-container-gallery">
            <h1>
              Image Gallery
              <button
                className="button"
                onClick={handleGetFiles}
              >
                Click me to get it !!!
              </button>
            </h1>
            <div className="image-container">
              <ul className="image-container__list">
                {imageGallery.length > 0 &&
                  imageGallery.map((image) => (
                    <li
                      style={{ listStyle: 'none' }}
                      key={image}
                    >
                      <img
                        src={image}
                        width="100%"
                      />
                      <button
                        type="button"
                        onClick={() => handleOnDelete(image)}
                      >
                        Delete file
                      </button>
                    </li>
                  ))}
              </ul>
            </div>
          </div>
        </div>
      );
    };
    
    export default Home;
    


    V. 그게. 잘 지내길 바랍니다.



    읽어주셔서 감사합니다
    좋은 하루 보내세요.

    Thang Em No Dev.

    좋은 웹페이지 즐겨찾기