본문 바로가기
[Study] 개발 공부

[React+Vite/TS] Firebase 쿼리와 패치

by 지공A 2024. 5. 30.

1. 인터페이스 작성

  • 사진은 없을 수 있음

2. useEffect를 사용하여 fetch 함수(쿼리)를 불러 올 것이다.

  • firebase의 query 함수를 사용
  • query(대상 컬렉션, 쿼리 조건 지정)
  • 대상 컬렉션 지정 시 firebase의 collection 함수 사용
  • collection(firestore 인스턴스, 컬렉션 이름)
  • 생성 순으로 내림차순 하기 위해 firebase의 orederBy 함수를 사용

3. 쿼리가 생성되었고, 이 쿼리를 사용하여 불러온 데이터를 저장하는 document를 가져올 것이다.

  • firebase의 getDocs 함수를 사용
  • getDocs(작성한 쿼리)
  • 이 함수는 쿼리의 결과인 QuerySnapshot를 반환한다.
  • 이 결과값으로 사진과 같이 여러 기능을 사용할 수 있다.
  • 이 결과값의 docs와 map을 활용하여 각 doc의 data를 추출한다.
  • 참고) id는 data에 직접 저장되는게 아니기 때문에, 각 doc의 id로 지정해주어야 한다.

4. 쿼리가 적용된 모든 데이터를 인터페이스에 부합한 형태로 반환하였고, 이를 state에 저장해주었다.

export interface IJweet {
  id: string;
  //   사진은 없을 수 있음
  photo?: string;
  jweet: string;
  userId: string;
  username: string;
  createdAt: number;
}

const Wrapper = styled.div``;

export default function Timeline() {
  const [jweets, setJweets] = useState<IJweet[]>([]);
  const fetchJweets = async () => {
    // jweets 컬렉션을 createdAt(생성) 내림차순으로 정렬하는 쿼리
    const jweetsQuery = query(
      collection(db, "jweets"),
      orderBy("createdAt", "desc")
    );
    // getDocs: QuerySnapshot 을 반환함
    const snapshot = await getDocs(jweetsQuery);
    // 참고: 개발모드에서 reacts.js가 useEffect 두번 호출
    const jweets = snapshot.docs.map((doc) => {
      const { jweet, createdAt, userId, username, photo } = doc.data();
      return {
        jweet,
        createdAt,
        userId,
        username,
        photo,
        // id는 data에 저장되는게 아니기 때문에
        id: doc.id,
      };
    });
    setJweets(jweets);
  };

  useEffect(() => {
    fetchJweets();
  }, []);
  return (
    <Wrapper>
      {jweets.map((jweet) => (
        <Jweet key={jweet.id} {...jweet}></Jweet>
      ))}
    </Wrapper>
  );
}