1일차 셋업/기본 로직 구현

2021. 4. 8. 01:25·Projects/JStargram_2021

목적: 파이어베이스를 사용해보고 싶었다. 백엔드에 들이는 시간을 아낄 수 있기에 프론트엔드 파트에 집중할 수 있을 것 같다.

컨셉: 유저들이 사진을 공유하고 사진에 대해 대화를 나눌 수 있는 반응형 채팅 웹. 파이어베이스의 소셜로그인과 실시간 데이터베이스 기능을 사용할 계획이다.


Initial Set-up

Set up react environment with necessary dependencies and new Firebase.

Connect App with database and Storage of Firebase.

 

리액트 개발환경을 세팅했다. 일단, 토이 프로젝트이기 때문에 많은 모듈은 필요하지 않다고 판단하여 styled component 정도만 적용했다.

 

파이어베이스에 데이터베이스와 스토리지(이미지저장) 을 생성하여 앱과 연결시켰다.

먼저, 파이어베이스 모듈을 설치하고 import 한 후, 생성 및 *초기화 한다.

*초기화: 객체를 선언하고 값을 할당하는 것.

import firebase from "firebase/app";
import "firebase/storage"; //store images
import "firebase/firestore"; //database
import "firebase/auth";
import dotenv from "dotenv";
dotenv.config();
// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
var firebaseConfig = {
  apiKey: process.env.REACT_APP_APIKEY,
  authDomain: process.env.REACT_APP_AUTHDOMAIN,
  projectId: process.env.REACT_APP_PROJECTID,
  storageBucket: process.env.REACT_APP_STORAGEBUCKET,
  messagingSenderId: process.env.REACT_APP_MESSAGESENDER,
  appId: process.env.REACT_APP_APPID,
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
// firebase.analytics();
const projectStorage = firebase.storage(); //This reference points to the root of Cloud Storage bucket.
const projectFirestore = firebase.firestore();
const timeStamp = firebase.firestore.FieldValue.serverTimestamp;
const projectAuth = firebase.auth();

export { projectStorage, projectFirestore, timeStamp, projectAuth };

Complete Basic Logics

- Upload form

- Firebase storage hook

- Make progress bar

- Firestore hook & showing image

- Create modal for selected image

 

1) 이미지 storage

이미지 파일을 storage 에 업로드하고, url 을 리턴받아 작성일자와 함께 파이어 데이터베이스에 올린다.

useEffect hooks 를 이용, file(이미지파일)에 변화가 생길때마다 즉, 새 이미지가 업로드될 때마다 데이터베이스에 추가시킨다.

ref() 는 해당 데이터베이스를 참조(바라보는 것)하는 메소드이다.

//useStorage.js

import { useState, useEffect } from "react";
import {
  projectStorage,
  projectFirestore,
  timeStamp,
} from "../firebase/config";

const useStorage = (file) => {
  const [progress, setProgress] = useState(0);
  const [error, setError] = useState(null);
  const [url, setUrl] = useState(null);

  useEffect(() => {
    //references : if images is uploaded in default storage, file.name should be used as a name
    const storageRef = projectStorage.ref(file.name);
    //collection is a container of documents
    //document is a unit of storage. It includes key-value objects
    const collectionRef = projectFirestore.collection("images");

    storageRef.put(file).on(
      "state_changed",
      (snap) => {
        let percentage = (snap.bytesTransferred / snap.totalBytes) * 100;
        setProgress(percentage);
      },
      (err) => {
        setError(err);
      },
      async () => {
        const url = await storageRef.getDownloadURL();
        const createdAt = timeStamp();
        collectionRef.add({ url, createdAt });
        setUrl(url);
      }
    );
  }, [file]);
  //useEffect callback will be fired if file dependency is changed
  return { progress, url, error };
};

export default useStorage;

ProgressBar.js 에서 framer-motion 라이브러리를 이용하여 애니메이션을 만든다.

//ProgressBar.js

import React, { useEffect } from "react";
import useStorage from "../hooks/useStorage";
import styled from "styled-components";
import { motion } from "framer-motion";

const ProgressBar = ({ file, setFile }) => {
  const { url, progress } = useStorage(file);
  //useStorage(file) returns { progress, url, error };
  // console.log(progress, url);

  useEffect(() => {
    if (url) {
      setFile(null);
    }
  }, [url, setFile]);

  return (
    <Progress
      percentage={progress}
      initial={{ width: 0 }}
      animate={{ width: progress + "%" }}
    >
      a
    </Progress>
  );
};

const Progress = styled(motion.div)`
  width: ${(props) => props.percentage + "%"};
  background: black;
  color: transparent;
`;

export default ProgressBar;

2) firestore

Firebase database(firestore) 해당 collection의 모든 사진들을 가져올 수 있다.

Collection 에 변화가 생길때마다(즉, 다큐먼트들) images 의 최신 데이터를 불러온다.

//useFirestore.js

import { useState, useEffect } from "react";
import { projectFirestore } from "../firebase/config";

const useFiretore = (collection) => {
  const [docs, setDocs] = useState([]);

  useEffect(() => {
    const unsub = projectFirestore
      .collection(collection) //collection will be 'images'
      .orderBy("createdAt", "desc")
      .onSnapshot((snap) => {
        //snapshot including all of documents in collection of
        //database when there is change in collection.
        let documents = [];
        snap.forEach((doc) => {
          documents.push({ ...doc.data(), id: doc.id });
          //doc.data(): all data of a document
        });
        setDocs(documents);
      });

    return () => unsub();
  }, [collection]);
  return { docs };
};

export default useFiretore;

ImageGrid.js 에서 데이터를 받아와 렌더시킨다.

import React from "react";
import useFiretore from "../hooks/useFirestore";
import styled from "styled-components";
import { motion } from "framer-motion";

const ImageGrid = ({ setSelectedImg }) => {
  const { docs } = useFiretore("images");
  // console.log(docs);
  return (
    <ImageBox>
      {docs &&
        docs.map((doc) => (
          <ImageWrap
            layout
            className="img-wrap"
            key={doc.id}
            onClick={() => setSelectedImg(doc)}
          >
            <Image
              src={doc.url}
              alt="uploaded pic"
              initial={{ opacity: 0 }}
              animate={{ opacity: 1 }}
              transition={{ delay: 1 }}
            />
          </ImageWrap>
        ))}
    </ImageBox>
  );
};

 

 

이미지

 

'Projects > JStargram_2021' 카테고리의 다른 글

4일차 CSS/기능 리팩토링 및 배포 완료  (0) 2021.04.09
3일차 파이어베이스 로그인/로그아웃 및 채팅 구현  (0) 2021.04.09
2일차 사진 갤러리 로직 및 CSS 완료  (0) 2021.04.08
'Projects/JStargram_2021' 카테고리의 다른 글
  • 4일차 CSS/기능 리팩토링 및 배포 완료
  • 3일차 파이어베이스 로그인/로그아웃 및 채팅 구현
  • 2일차 사진 갤러리 로직 및 CSS 완료
JTB
JTB
웹/앱 개발 정보를 공유하고 있습니다.
  • JTB
    JTechBlog
    JTB
  • 전체
    오늘
    어제
    • All About Programming;) N
      • Computer Science
        • Terminology and Concepts
        • Network
        • Operating System
        • Database
        • Data Structure
      • Frontend
        • Javascript Essentials
        • Perfomance Optimization
        • JS Patterns
        • Next.js
        • Flutter
      • Backend
        • Node.js
      • DevOps
        • Docker & Kubernetes
      • Coding Test N
        • LeetCode N
        • Programmers
      • Tech Books & Lectures
        • Javascript_Modern JS Deep d..
        • Network_IT 엔지니어를 위한 네트워크 입문
      • Projects
        • PolyLingo_2025
        • Build Your Body_2024
        • JStargram_2021
        • Covid19 Tracker_2021
        • JPortfolio_2021
      • BootCamp_Codestates
        • TIL
        • TILookCloser
        • Pre Tech Blog
        • IM Tech Blog
        • Daily Issues and DeBugging
        • First Project
        • Final Project
        • Sprint Review
        • Good to Know
        • Socrative Review
        • HTML &amp; CSS
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 글쓰기
    • 관리
  • 공지사항

  • 인기 글

  • 태그

    CPU scheduling algorithm
    TCP/IP
    Threads and Multithreading
    JavaScript
    Shared resources
    leetcode
    스코프
    딥다이브
    Network
    Data Structure
    testing
    모던 자바스크립트 Deep Dive
    js pattern
    Binary Tree BFS
    indie hacker
    DOM
    mobile app
    자바스크립트 딥다이브
    structure of os
    VoiceJournal
    커리어
    need a database
    How memory manage data
    database
    이벤트
    Operating System
    프론트엔드 성능 최적화 가이드
    polylingo
    자바스크립트
    Time complexity and Space complexity
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
JTB
1일차 셋업/기본 로직 구현
상단으로

티스토리툴바