로그인시 사용자 컬렉션에서 사용자 데이터 가져 오기
Nov 21 2020
현재 클라이언트 측에서 firebase가 초기화 된 애플리케이션에서 작업 중입니다. 사용자가 firebase를 통해 로그인 할 때 firestore에서 사용자 데이터를 가져오고 싶습니다. 현재 onAuthStateChanged
리스너 내에서 수행하고 있으며 사용자를 성공적으로 가져옵니다. 이것이 사용자 데이터를 가져 오는 가장 좋은 방법인지 궁금합니다. 내 코드는 다음과 같습니다.
const [currentUser, setCurrentUser] = useState(null)
const [authState, setAuthState] = useState(false)
useEffect(() => {
console.log('state unknown')
setAuthState(false)
auth().onAuthStateChanged(user => {
if (!user) {
return
}
const sourceRef = firestore()
.collection('users')
.where('userId', '==', user.uid)
sourceRef
.get()
.then(snapshot => {
if (snapshot.empty) {
console.log('user not found')
} else {
let data = {}
snapshot.forEach(item => (data = item.data()))
console.log(data)
setCurrentUser(data)
setAuthState(true)
}
})
.catch(error => console.log(error.code))
})
}, [])
return (
<AppContext.Provider value={{ currentUser, authState }}>
{children}
</AppContext.Provider>
)
}
내 주요 관심사는 응용 프로그램을 새로 고칠 때마다 사용자의 데이터를 가져 오는 것입니다. 문제에 대한 제안이나 모범 사례는 대단히 감사하겠습니다.
답변
2 LouisCoulet Nov 21 2020 at 17:55
컨텍스트 API 및 인증 관찰자를 사용하는 IMHO 접근 방식은 사소한 문제만으로 이미 훌륭합니다.
- Awran5에서 언급 한대로 옵저버 구독을 취소해야합니다.
- 사용자 데이터를 한 번만 가져 오는 대신 관찰 할 수 있습니다.
- 가독성과 성능을 위해 컨텍스트를 분리 할 수 있습니다.
- 소유자의 ID로 컬렉션 사용자에서 문서를 만들 수 있으므로
collection("users").doc(authUser.uid)
쿼리를 수행하는 대신 직접 액세스 할 수 있습니다.
다음은 귀하의 예를 수정하는 방법입니다. 최선의 방법인지 확실하지 않은 경우 다른 의견을 기다리고 있습니다.
const AuthContext = React.createContext();
function AuthProvider({ children }) {
const [authUser, setAuthUser] = React.useState(undefined);
React.useEffect(() => {
return firebase.auth().onAuthStateChanged(user => setAuthUser(user));
}, []);
return <AuthContext.Provider value={authUser}>{children}</AuthContext.Provider>;
}
const UserDataContext = React.createContext();
function UserDataProvider({ children }) {
const [userData, setUserData] = React.useState(null);
const authUser = React.useContext(AuthContext);
React.useEffect(() => {
if (!authUser) return;
const query = firebase.firestore().collection("/users").where("userId", "==", authUser.uid);
return query.onSnapshot(snapshot => setUserData(snapshot.empty ? null : snapshot.docs[0].data()));
}, [authUser]);
return <UserDataContext.Provider value={userData}>{children}</UserDataContext.Provider>;
}
export default function App() {
return (
<AuthProvider>
<UserDataProvider>
{/* ... other components */}
<MyComponent />
</UserDataProvider>
</AuthProvider>
);
}
function MyComponent() {
const authUser = React.useContext(AuthContext);
const userData = React.useContext(UserDataContext);
if (authUser === undefined) return <div>loading user authentication...</div>;
if (authUser === null) return <div>logged out</div>;
return <div>User data: {JSON.stringify(userData)}</div>;
}
구성 요소는 인증 상태 변경 또는 사용자 데이터 변경시 여전히 다시 렌더링되지만 필요한 경우에만 해당됩니다.