๐ŸŒŸ Cloud Firestore๋กœ ์‹ค์‹œ๊ฐ„ ์—…๋ฐ์ดํŠธ ๊ฐ€์ ธ์˜ค๊ธฐ

summereuna๐Ÿฅยท2022๋…„ 4์›” 3์ผ

๐ŸŒŸ Twinkle (React, Firebase)

๋ชฉ๋ก ๋ณด๊ธฐ
15/42

์‹ค์‹œ๊ฐ„ ๊ธ€ ์ž‘์„ฑ


๊ทธ๋‚˜์ €๋‚˜ ํ˜„์žฌ ํŠธ์œ—์„ ๋‚ ๋ฆฌ๋ฉด ๋ฐ”๋กœ๋ฐ”๋กœ ํ™”๋ฉด์— ๋ณด์—ฌ์ง€์ง€ ์•Š๊ณ  ์ƒˆ๋กœ๊ณ ์นจํ•ด์•ผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๋ฐ›์•„์™€์„œ ํŠธ์œ—์„ ๋ Œ๋”ฉํ•œ๋‹ค.

์ƒˆ๋กœ ์ƒ์„ฑ๋˜๋Š” ํŠธ์œ—์ด ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ณด์—ฌ์ง€๊ฒŒ ๋งŒ๋“ค์–ด ๋ณด์ž.
๊ทธ๋Ÿฌ๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ฝ”๋“œ๋ฅผ ์ข€ ๋งŽ์ด ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค.(๋ˆˆ๋ฌผ๐Ÿฅฒ)


onSnapshot() ๋ฉ”์„œ๋“œ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ณ€ํ™”๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์•Œ๋ ค์ค€๋‹ค.

  • ๋”ฐ๋ผ์„œ onSnapshot()๋ฉ”์„œ๋“œ๋กœ Document๋ฅผ ์ˆ˜์‹ (listen)ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ œ๊ณตํ•œ ์ฝœ๋ฐฑ์„ ์‚ฌ์šฉํ•œ ์ดˆ๊ธฐ ํ˜ธ์ถœ์€ ๋‹จ์ผ Document์˜ ํ˜„์žฌ ๋‚ด์šฉ์„ ํฌํ•จํ•œ Document ์Šค๋ƒ…์ƒท์„ ์ฆ‰์‹œ ์ƒ์„ฑํ•œ๋‹ค.
  • ๊ทธ๋Ÿฐ ๋‹ค์Œ ๋‚ด์šฉ์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค, ๋‹ค๋ฅธ ํ˜ธ์ถœ์ด Document ์Šค๋ƒ…์ƒท์„ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.
//๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ญ”๊ฐ€ ํ•˜๊ฒŒ ๋˜๋ฉด ์•Œ ์ˆ˜ ์žˆ๋„๋ก ์ฝ˜์†”์„ ์ฐ์–ด๋ณด์ž!
useEffect(() => {
  getTweets();
  const q = query(collection(dbService, "tweets"));
  onSnapshot(q, (snapshot) => {
    console.log("Something happen!");
  });
}, []);
  • ํŽ˜์ด์ง€๊ฐ€ ๋ Œ๋”๋˜๋ฉด ์ฝ˜์†”์— "Something happen!"๊ฐ€ ์ฐํžŒ๋‹ค.

  • ํŠธ์œ— ๋‚ด์šฉ์„ ์ž…๋ ฅํ•  ๋•Œ "Something happen!"์ด ํ•œ ๋ฒˆ ๋” ์ฐํžˆ๊ณ ,
    ์ž…๋ ฅ ํ›„ "Something happen!"์ด ํ•œ ๋ฒˆ ๋” ๋œฌ๋‹ค.

๋ฆฌ๋ Œ๋”๋ง ๊ตณ์ด ํ•„์š” ์—†๋Š”๋ฐ ๊ณ„์† ๋˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์˜ค๋ž˜๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ธฐ์กด์˜ forEach()์—์„œ ์ƒˆ๋กœ ์ƒ์„ฑ/๋ณ€๊ฒฝ๋œ ๋ฐ์ดํ„ฐ๋Š” ์ƒˆ๋กœ๊ณ ์นจํ•ด ๋ฐ˜์˜๋˜๋Š” map()์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜์ž!

  • ๊ตฌ๋ฐฉ๋ฒ•
    forEach๋กœ ๋‹คํ๋จผํŠธ ๋‚˜์—ด
//ํŠธ์œ— ๋ฐ›๋Š” ๋ฐฉ๋ฒ•
  const getTweets = async () => {
    /*1. DB์—์„œ ์ปฌ๋ ‰์…˜ ๊ฐ€์ ธ์˜ค๊ธฐ
    dbService์— ์žˆ๋Š” tweets ์ปฌ๋ ‰์…˜์„ ๊ฐ€์ ธ์˜ค๋Š” ์ฟผ๋ฆฌ ๋งŒ๋“ค๊ธฐ*/
    const q = query(collection(dbService, "tweets"));
    /*2. ์ปฌ๋ ‰์…˜์˜ ๋‹คํ๋จผํŠธ ๋ชจ๋‘ ๊ฐ€์ ธ์˜ค๊ธฐ
    - ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ QuerySnapshot์œผ๋กœ ๋ฐ˜ํ™˜ํ•˜๋ฉด tweets ์ปฌ๋ ‰์…˜์˜ document๋“ค์„ ์–ป๋Š”๋‹ค.
    - ๋”ฐ๋ผ์„œ querySnapshot์€ tweets ์ปฌ๋ ‰์…˜์˜ document๋“ค์„ ๋ชจ์•„๋†“์€ ๋ฐฐ์—ด์ด๋‹ค.*/
    const querySnapshot = await getDocs(q);
    //3. ๊ฐ๊ฐ์˜ ๋‹คํ๋จผํŠธ๋ฅผ ๋‚˜์—ด
    querySnapshot.forEach((document) => {
      /*๊ฐ๊ฐ์˜ ๋‹คํ๋จผํŠธ๋ฅผ ๋‚˜์—ดํ•  ๋•Œ {data, id} ์˜ค๋ธŒ์ ํŠธ ํ˜•ํƒœ๋กœ ๋‚˜์—ดํ•˜์ž.
    - document์˜ data๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด data() ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ
    - ํŠธ์œ— ํ•˜๋‚˜์”ฉ ๋‚˜์—ด ํ•  ๋•Œ ์“ธ key ๊ฐ’ ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— id ํ• ๋‹น*/
      const tweetObj = {
        ...document.data(),
        id: document.id,
      };
      //- setTweets() ๋ชจ๋””ํŒŒ์ด์–ด๋กœ ์ด์ „ tweets(prev)์— ๋Œ€ํ•ด, ์ƒˆ๋กœ์šด ๋ฐฐ์—ด(์ƒˆ๋กœ ์ž‘์„ฑํ•œ ํŠธ์œ—๊ณผ, ...๊ทธ ์ด์ „ ๊ฒƒ๋“ค)์„ ๋ฆฌํ„ดํ•ด์ฃผ์ž.
      setTweets((prev) => [tweetObj, ...prev]);
    });
  };
//
  //4. ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ๋˜๋ฉด useEffect()์‚ฌ์šฉ
  useEffect(() => {
    getTweets();
    const q = query(collection(dbService, "tweets"));
    onSnapshot(q, (snapshot) => {
      console.log("Something happen!");
    });
  }, []);
  • ์‹ ๋ฐฉ๋ฒ•
    map์œผ๋กœ ๋‚˜์—ด: ๋ฆฌ๋ Œ๋” ์•ˆ๋˜๊ณ  ํ•œ ๋ฒˆ๋งŒ ๋ฐœ์ƒ (๋” ํšจ์œจ์ )
import React, { useEffect, useState } from "react";
import { dbService } from "fbase";
import {
  collection,
  addDoc,
  serverTimestamp,
  query,
  onSnapshot,
  orderBy,
} from "firebase/firestore";

//App > Router > Home ์ˆœ์œผ๋กœ ๋ณด๋‚ธ ๋กœ๊ทธ์ธํ•œ ์œ ์ € ์ •๋ณด prop์œผ๋กœ ๋ฐ›๊ธฐ
const Home = ({ userObj }) => {
  //ํ™ˆ์—์„œ ํŠธ์œ— ๋‚ด์šฉ ์ž‘์„ฑํ•˜๋Š” ํผ
  const [tweet, setTweet] = useState("");

  //0. ์ž‘์„ฑํ•œ ํŠธ์œ— ๊ฐ€์ ธ์˜ค๊ธฐ: ๊ธฐ๋ณธ ๊ฐ’์€ ๋นˆ ๋ฐฐ์—ด
  const [tweets, setTweets] = useState([]);

  //๐Ÿ”ฅํŠธ์œ— ๊ฐ€์ ธ์˜ค๊ธฐ: map์œผ๋กœ
  useEffect(() => {
    //snapshot์€ ์ฟผ๋ฆฌ ๊ฐ™์€ ๊ฑด๋ฐ docs๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
    //tweets์€ ํŽ˜์ด์ง€๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ snapshot์—์„œ ๋‚˜์˜ค๋Š” ๊ฑฐ๋‹ค.
    //๋”ฐ๋ผ์„œ setTweets()์„
    const q = query(
      collection(dbService, "tweets"),
      orderBy("createdAt", "desc")
    );
    const unsubscribe = onSnapshot(q, (snapshot) => {
      //๋ชจ๋“  docs๋Š” {} ์˜ค๋ธŒ์ ํŠธ ๋ฐ˜ํ™˜ํ•˜๋„๋ก
      //์•„์ด๋”” ๊ฐ€์ ธ์˜ค๊ณ , ๊ทธ๋ฆฌ๊ณ  ๋‚˜๋จธ์ง€ ๋ฐ์ดํ„ฐ ์ „์ฒด ๊ฐ€์ ธ์˜ค๊ธฐ
      const tweetArr = snapshot.docs.map((doc) => ({
        id: doc.id,
        ...doc.data(),
      }));
      //ํŠธ์œ—์–ด๋ ˆ์ด ํ™•์ธํ•ด๋ณด์ž. ์˜ค์ผ€์ด ์›ํ•˜๋Š”๋Œ€๋กœ ํฌ๋งท๋œ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค!
      console.log(tweetArr);
      setTweets(tweetArr);
    });
    return () => {
      unsubscribe();
    };
  }, []);

  const onSubmit = async (event) => {
    event.preventDefault();
    //ํŠธ์œ—ํ•˜๊ธฐ ๋ˆ„๋ฅด๋ฉด ์ƒˆ๋กœ์šด document ์ƒ์„ฑํ•˜๊ธฐ
    try {
      const docRef = await addDoc(collection(dbService, "tweets"), {
        //ํŠธ์œ— ์ž‘์„ฑ์ž
        creatorId: userObj.uid,
        text: tweet, //tweet(value๋กœ tweet state ๊ฐ’)
        createdAt: serverTimestamp(), //Date.now(),๋กœ ํ•ด๋„ ๋˜์ง€๋งŒ ์ด์™• ์žˆ๋Š”๊ฑฐ ํ•จ ์จ๋ณด์ž(ํƒ€์ž„์กด ๋™๋ถ์•„3 = ์„œ์šธ๋กœ ์„ค์ •๋˜์–ด ์žˆ์Œ)
      });
      //console.log("Document written with ID: ", docRef.id);
    } catch (error) {
      console.error("Error adding document: ", error);
    }
    //state ๋น„์›Œ์„œ form ๋น„์šฐ๊ธฐ
    setTweet("");
  };

  const onChange = (event) => {
    const {
      target: { value },
    } = event;
    setTweet(value);
    //console.log(tweet);
  };

  return (
    <>
      <div>
        <form onSubmit={onSubmit}>
          <input
            type="text"
            placeholder="๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๊ณ  ์žˆ๋‚˜์š”?"
            maxLength={120}
            value={tweet}
            onChange={onChange}
          />
          <input type="submit" value="ํŠธ์œ—ํ•˜๊ธฐ" />
        </form>
      </div>
      {/*DB์—์„œ ๊ฐ€์ ธ์˜จ ํŠธ์œ„ํ„ฐ ๋‚˜์—ด*/}
      <div>
        {tweets.map((tweet) => (
          //tweetObj ๋งŒ๋“ค ๋•Œ ๊ฐ๊ฐ์˜ tweet์— ํ• ๋‹นํ•œ id ๊ฐ’์„ div์˜ key์— ๋„ฃ์–ด์ฃผ์ž
          <div key={tweet.id}>
            <h4>{tweet.text}</h4>
          </div>
        ))}
      </div>
    </>
  );
};

export default Home;

์ฐธ๊ณ 

profile
Always have hope๐Ÿ€ & constant passion๐Ÿ”ฅ

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