✍️ Today what I Learned _TIL

[팀 프로젝트(React)] 문제해결: date객체 (ISO)String으로 변환해 Firestore에 넣고, 가져와 시간 뜨게하기 / 시간순 정렬

련디 2024. 2. 15. 13:18
SMALL

240215 TIL

 

React 뉴스피드 팀프로젝트 (프론트엔드) 를 하면서 백엔드 서비스는 Firebase를 활용해서 했었다-!

 

firebase의 firestore에 게시글 posts 컬렉션을 만들고, 그 안에 게시글 하나하나 아이템을 문서로서, 데이터를 넣어야 했는데.. 그 중 한 필드로 date가 있었다. 글 쓴 시각을 date 필드값에 넣어주고, 그 시간을 read 조회하면서 꺼내와야 했다.

 

게시글을 올리면, 메인페이지에서 글쓴 날짜와 시간까지 뜨도록 하기

 

이 과정에서 약간 문제가 있었는데 ... ㅠㅠ

일단, 직접 date에 대한 value값을 파이어스토어에서 timestamp 를 활용해서 찍어봤더니..

파이어스토어 통해 데이터를 가져올 때, 이 date 필드에 대한 value값이 timestamp 형태로 들어오기 때문에..

이걸 조회하면서 페이지에 뜨게 하려면 -> string으로 변환을 해줘야 했다. 

- 아마 이 때 나는 timestamp객체를 -> toDate 메서드로 Date객체로 변환 -> toLocaleString 메서드 써서

이중 변환을 해서 썼던 것 같다.

 

즉 해당 timestamp객체가  'date' 라면,

date.toDate().toLocaleDateString("ko-KR", {
             year: "numeric",
            month: " numeric ",
            day: "numeric",

            .....        })

이런 식으로 !

 

 

 

근데.. ㅠㅠ 글쓰기를 통해 여기에 문서를 추가하려면은.. (직접 파이어베이스에서 문서추가가 아닌)

timestamp나 date 등의 객체가 안들어가는 거 같았다 ....

string형태로만 들어가는 듯 했다. 

그래서 데이터를 또 넣을 때엔, string 형식으로 넣어줬다. 

 

근데 toLocaleString로 변환할 수도 있었지만 다시 꺼내올 때 date객체가 필요했고

(timestamp가 아닌 date객체를 통해 sort 정렬을 하고 싶었기 때문인데 ..근데 생각해보니까 그냥 timestamp를 통해 정렬해도 됐을 거 같은데...?)

 

 

구글링 중

" new Date(string)은 인자로 전달된 문자열을 파싱하여 Date 객체로 만듭니다. 여기서 문자열은 YYYY-MM-DD와 같은 ISO 8601 형식이어야 합니다. "

라는 걸 보고, 나중에 new Date로 변환하기 좋은 ISO 문자열 형식으로 데이터를 넣기로 했다.

 

 

그래서,

처음에 firestore에  date를 넣을 때 

date : new Date().toISOString()   이렇게 ISOString (  toLocaleString 이 아닌) 으로 변환해 넣도록 한 후

 

 

가져올 때는 다시 date객체로 변환해서, 그걸 통해 sort 시간 순으로 정렬해서 리스트를 조회하도록 했다.

( 아래코드- 만들어둔 posts, category 모듈 사용 /  useEffect 안은 firebase 데이터 가져오기 )

    const setPosts = useSelector((state) => state.posts);
    const activeCategory = useSelector((state) => state.category);
    const dispatch = useDispatch();

    useEffect(() => {
        const fetchData = async () => {
            // firestore db 가져오기
            const q = query(collection(db, "posts"));
            const querySnapshot = await getDocs(q);

            const initialPosts = [];

            querySnapshot.forEach((doc) => {
                initialPosts.push({ id: doc.id, ...doc.data() });
            });

            // date 날짜시간순 정렬
            const dateOrderedPosts = [...initialPosts].sort((a, b) => {
                return new Date(b.date) - new Date(a.date); // post컬렉션 문서의 date키 밸류값은 ISO String이므로 date객체로 변환해준 후 sort
            });

            // firestore에서 가져온 데이터를 redux 통해 전달
            dispatch(setPost(dateOrderedPosts));
        };
        fetchData();
    }, []);
    const filteredPosts = setPosts.filter((post) => post.category === activeCategory);

 

 

 

그리고 isoString인 date밸류값(문자열)을 -> new Date 메서드로 다시 date객체로 만들어 -> toLocaleString을 써서 조회 시 뜨게 함

    // 가져온 post의 date : ISO String 이므로 다시 date객체로 변환해 -> toLocale..String으로 0000. 00. 00. 오전(오후) 0:00 형태로 변환
    const formattedDate = new Date(date).toLocaleDateString("ko-KR", {
        year: "numeric",
        month: "numeric",
        day: "numeric",
        hour: "numeric",
        minute: "numeric",
    });

 

 

 

 

구글 Firebase의 firestore database - posts 컬렉션 중 한 문서 여기 date필드에대한 값이 ISO String형식이다

 

 

더 좋은 방법이 있을지도..?!

이렇게 글을 써보니 또 복잡하다ㅠㅠ

 

 

 

💡정리하자면 나는,

 데이터 넣을 때는 isoString으로 넣고,

이걸 가져와 페이지에 문자열로 뜨게 할 때에는, new Date -> toLocaleString 을 썼고

sort메서드로 date순 정렬 할 때에는, 가져온 걸 new Date 해서 비교해서 정렬하는 식으로

해결 !! *_*

SMALL