코딩

트위터 클론 :4 Profile화면에서 내 트윗가져오기, user 정보 업데이트하기

코딩쪼렙 2023. 3. 2. 12:44
728x90

profile에서 내 nweet을 가져오기 

이 프로필은 내가 누구인지 몰라 아무나의 프로필을 가져올 수 없어 

rotuer->profile prop으로 userObj 전달

 

✅ 쿼리 필터링하기
[참고]
- 컬렉션에서 여러 문서 가져오기: https://firebase.google.com/docs/firestore/query-data/get-data#get_multiple_documents_from_a_collection

- 데이터 정렬 및 제한: https://firebase.google.com/docs/firestore/query-data/order-limit-data#order_and_limit_data

v.9
```
import { authService, dbService } from "fbase";
import { collection, getDocs, query, where, orderBy } from "firebase/firestore";
import { useEffect } from "react";
//...

//1. 로그인한 유저 정보 prop으로 받기
const Profile = ({ userObj }) => {
//...

//2. 내 nweets 얻는 function 생성
const getMyNweets = async () => {
//3. 트윗 불러오기
//3-1. dbService의 컬렉션 중 "nweets" Docs에서 userObj의 uid와 동일한 creatorID를 가진 모든 문서를 내림차순으로 가져오는 쿼리(요청) 생성
const q = query(
collection(dbService, "nweets"),
where("creatorId", "==", userObj.uid),
orderBy("createdAt", "desc")
);

//3-2. getDocs()메서드로 쿼리 결과 값 가져오기
const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
console.log(doc.id, "=>", doc.data());
});
};

//4. 내 nweets 얻는 function 호출
useEffect(() => {
getMyTweets();
}, []);

return (
<>
로그아웃
</>
);
};

 

USER정보 업데이트하기


export default Profile;

 

import { authService, dbService } from "fbase";
import React, { useState } from "react";
import { useNavigate } from "react-router-dom";

import { updateProfile } from "firebase/auth";

export default function Profile({ userObj }) {
    console.log(userObj);

    const navigate = useNavigate();
    const [newDisplayName, setNewDisplayName] = useState(userObj.displayName);
    const onLogoutClick = () => {
        authService.signOut();
        navigate("/");
    };

    const onChange = (event) => {
        const {
            target: { value },
        } = event;
        setNewDisplayName(value);
    };
    const onSubmit = async (event) => {
        event.preventDefault();
        if (userObj.displayName !== newDisplayName) { 이름 바뀔 때 업데이트 
            await updateProfile(userObj, {
                displayName: newDisplayName,
            });
        }
    };
    return (
        <>
            <form onSubmit={onSubmit}>
                <input
                    onChange={onChange}
                    type="text"
                    placeholder="Display Name"
                    value={newDisplayName}
                />
                <input type="submit" value="UpdateProfile" />
            </form>
            <button onClick={onLogoutClick}>Logout</button>
        </>
    );
}

 

displayName SUBMIT해도

해당 navigation에 바로 업데이트 되지않는에러 

 

navigation은 app(react)의 userObj를 받아온것이기 때문에 해당 userobj firebase에서 가져와서 업데이트해야함  

 


function App() {
    const [init, setInit] = useState(true);
    const [userObj, setUserObj] = useState(null);
    useEffect(() => {
        authService.onAuthStateChanged((user) => {
            user ? setUserObj({
                displayName:user.displayName,
                uid:user.uid,

            }) : setUserObj(null);
            setInit(true);
        });
    }, []);
const refreshUser = ()=>{
    const user = authService.currentUser;
    setUserObj({
        displayName:user.displayName,
        uid:user.uid,

    })
}
    return (
        <>
            {init ? (
                <AppRouter isLoggedIn={Boolean(userObj)} userObj={userObj} refreshUser={refreshUser}/>
            ) : (
                "Initializng..."
            )}
            <footer>&copy; {new Date().getFullYear()} Twitter</footer>
        </>
    );
}

 

appRouter->profile 전달

 

 


export default function Profile({ userObj, refreshUser }) {
    console.log(userObj);

    const navigate = useNavigate();
    const [newDisplayName, setNewDisplayName] = useState(userObj.displayName);
    const onLogoutClick = () => {
        authService.signOut();
        navigate("/");
    };

    const onChange = (event) => {
        const {
            target: { value },
        } = event;
        setNewDisplayName(value);
    };
    const onSubmit = async (event) => {
        event.preventDefault();
        if (userObj.displayName !== newDisplayName) {
            await updateProfile(authService.currentUser, {
                displayName: newDisplayName,
            });
            refreshUser();
        }
    };
    return (
        <>
            <form onSubmit={onSubmit}>
                <input
                    onChange={onChange}
                    type="text"
                    placeholder="Display Name"
                    value={newDisplayName}
                />
                <input type="submit" value="UpdateProfile" />
            </form>
            <button onClick={onLogoutClick}>Logout</button>
        </>
    );
}

 

 

if (user) {
setUserObj({
displayName: user.displayName,
uid: user.uid,
updateProfile: (args) => user.updateProfile(args),
});
} else {
setUserObj(null);
}

setUserObj 방식을  오늘처럼 바꾸고 나니까 이렇게 해줘야 로그아웃시에 로그인화면으로 제대로 돌아가네요. else 문 (강의에는 없던 부분)을 빼면 로그아웃 후 refresh를 해줘야 제대로 로그아웃 됩니다.