트위터 클론코딩) firestore database에서 tweet 가져오기(v9)

Hyemimi·2022년 7월 15일
0
post-thumbnail

collection/ getDocs /query + forEach 사용해서 database 가져오기

0. import

import { collection,getDocs, query } from "firebase/firestore";

1. getDocs

const [tweets, setTweets] = useState([]);

const getTweets = async () => {
    const dbTweets = 
          await getDocs(collection(db, "tweets"));
console.log(dbTweets)}
  • output :

console을 살펴보면 dbTweets은 우리가 원하는 트윗의 내용이 아니다. 트윗의 내용을 가져오려면 forEach를 이용해서 doc 하나하나를 순회하고, data()함수를 이용해서 가져올 수 있다.

2. forEach

const getTweets = async () => {
    const dbTweets = await getDocs
    (collection(db, "tweets"));
    dbTweets.forEach((document) => {
      console.log(document.data());
      };
    });
  };
  • output :

가져오기 성공!

그런데 우리는 트윗 리스트를 웹에서 보여주어야 하므로,
tweetObject라는 객체를 만들어서 위의 data + id까지 넣어준 뒤, useState를 이용해 tweet의 내용을 계속 갱신할 수 있도록 할 것이다.


const tweetObject = {
        ...document.data(),
        id: document.id,
      };

tweetObject는 바로 이렇게 앞에서의 데이터와, id를 할당해준 객체이다.

const getTweets = async () => {
    const dbTweets = await getDocs
    (collection(db, "tweets"));
    dbTweets.forEach((document) => {
      const tweetObject = {
        ...document.data(),
        id: document.id,
      };
      setTweets((prev) => [tweetObject, ...prev]);
    });
  };

setTweets()를 이용해서 tweets의 상태변화가 가능하도록 만들어주었다.
이제 useEffect(()=>{},[]) 훅을 이용해서 tweet이 갱신될 때마다 갱신된 트윗의 리스트를 가져올 수 있도록 getTweets함수를 불러오면 끝


[fbase.js]

import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
import { getFirestore } from "firebase/firestore";
// Your web app's Firebase configuration

const firebaseConfig = {
 // secrets
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);

export default app;
export const auth = getAuth(app);
export const db = getFirestore(app);

[Home.js]

import { db } from "fbase";
import React, { useEffect, useState } from "react";
import { collection, addDoc, getDocs, query } from "firebase/firestore";

const Home = () => {
  const [tweet, setTweet] = useState("");
  const [tweets, setTweets] = useState([]);

  const getTweets = async () => {
    const dbTweets = await getDocs(collection(db, "tweets"));
    console.log(dbTweets);
    dbTweets.forEach((document) => {
      console.log(document.data());
      const tweetObject = {
        ...document.data(),
        id: document.id,
      };
      setTweets((prev) => [tweetObject, ...prev]);
    });
  };

  useEffect(() => {
    getTweets();
  }, []);

  const onSubmit = async (event) => {
    event.preventDefault();
    await addDoc(collection(db, "tweets"), {
      tweet,
      createdAt: Date.now(),
    });
    setTweet("");
  };
  const onChange = (event) => {
    setTweet(event.target.value);
  };
  console.log(tweets);
  return (
    <div>
      <form onSubmit={onSubmit}>
        <input
          type="text"
          value={tweet}
          onChange={onChange}
          placeholder="What's on your mind?"
          maxLength={120}
        />
        <input type="submit" value="Tweet" />
      </form>
      <div>
        {tweets.map((tweet, idx) => (
          <div key={tweet.id}>
            <h4>
              {idx + 1} : {tweet.tweet}
            </h4>
          </div>
        ))}
      </div>
    </div>
  );
};

export default Home;

tweetsmap()을 이용해서 요소 하나하나에 접근할 수 있다.

  • output :

collection,
query,
orderBy,
onSnapshot 이용해서 가져오기

useEffect(() => {
  const q = query(collection(db, "tweets"), 
                  orderBy("createdAt", "desc"));
  onSnapshot(q, (snapshot) => {
    const tweetArr = snapshot.docs.map((document) => ({
      id: document.id,
      ...document.data(),
    }));
    setTweets(tweetArr);
  });
}, []);

강의에서 소개한 또 다른 방법인데, 버전9의 경우 위와 같이 코딩하면 된다.

profile
암냠냠

0개의 댓글