英文:
Get currentUser not working with firestore and react
问题
I've created a simple sign-up in which the user provides their name, bio, and profile picture. Currently, I am trying to display a logged-in user's data, however, I'm not having much luck doing so.
The issue here is that the data is not being retrieved (from the fact that my console only prints out "nothing"). I used the firestore documentation to create the getUser()
function and am at a loss as to why it doesn't work.
import { useAuth } from "../../contexts/authContext";
import firebase from "firebase/compat/app";
import "firebase/compat/storage";
import "firebase/compat/firestore";
async function getUser() {
const userRef = firestore
.collection("users")
.doc(firebase.auth().currentUser.uid);
userRef.get().then(function (doc) {
if (!doc.exists) {
console.log("nothing");
} else {
console.log("document", doc.data().name);
}
});
}
useEffect(() => {
getUser();
}, [])
I've tried a lot of different methods, but none of which are giving me the results I want. I've attempted to use reactfire
but I am in the process of debugging that as well. I've been researching this for days and feel clueless. Thanks for any input you can provide, I appreciate it.
英文:
I've created a simple sign-up in which the user provides their name, bio, and profile picture. Currently, I am trying to display a logged-in user's data, however, I'm not having much luck doing so.
The issue here is that the data is not being retrieved (from the fact that my console only prints out "nothing"). I used the firestore documentation to create the getUser()
function and am at a loss as to why it doesn't work.
import { useAuth } from "../../contexts/authContext";
import firebase from "firebase/compat/app";
import "firebase/compat/storage";
import "firebase/compat/firestore";
async function getUser() {
const userRef = firestore
.collection("users")
.doc(firebase.auth().currentUser.uid);
userRef.get().then(function (doc) {
if (!doc.exists) {
console.log("nothing");
} else {
console.log("document", doc.data().name);
}
});
}
useEffect(() => {
getUser();
}, [])
I've tried a lot of different methods, but none of which are giving me the results I want. I've attempted to use reactfire
but I am in the process of debugging that as well. I've been researching this for days and feel clueless. Thanks for any input you can provide, I appreciate it.
答案1
得分: 0
正如@samthecodingman建议的那样,我们不应该在新项目中使用紧凑的库。这里有一个示例,使用了新的模块化Firebase API。
我有一个基于上下文的示例:在App.tsx中,数据组件包装在AuthProvider中:
AuthProvider.tsx:
import {
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
signOut,
User,
} from "firebase/auth";
import { doc, getDoc } from "firebase/firestore";
import React from "react";
import { auth, db } from "../config/firebase";
type ContextType = {
user: User | null;
loading: boolean;
login: (email: string, password: string) => Promise<User>;
register: (email: string, password: string) => Promise<User>;
logOut: () => Promise<void>;
getUserData: () => Promise<void>;
};
const AuthContext = React.createContext({} as ContextType);
export function useAuth() {
return React.useContext(AuthContext);
}
export const AuthProvider = ({ children }: React.PropsWithChildren) => {
const [currentUser, setCurrentUser] = React.useState<User | null>(null);
const [loading, setLoading] = React.useState(true);
async function login(email: string, password: string) {
const userCredential = await signInWithEmailAndPassword(auth, email, password);
return userCredential.user;
}
async function register(email: string, password: string) {
const userCredential = await createUserWithEmailAndPassword(auth, email, password);
return userCredential.user;
}
async function getUserData() {
if(auth.currentUser) {
console.log("User: ", auth.currentUser);
const userRef = doc(db, "users", auth.currentUser?.uid);
const data = await getDoc(userRef);
if(!data.exists()) console.log("Not Found");
else console.log("User Data Found: ", data.data());
} else console.log("User Not Found");
}
function logOut() {
return signOut(auth);
}
React.useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((user) => {
setCurrentUser(user);
setLoading(false);
});
return unsubscribe;
}, []);
const value = {
user: currentUser,
loading: loading,
login: login,
register: register,
logOut: logOut,
getUserData: getUserData
};
return (
<AuthContext.Provider value={value}>
{!loading && children}
</AuthContext.Provider>
);
};
Data.tsx:
import { useEffect } from "react";
import { useAuth } from "./contexts/AuthProvider";
export default function Data() {
const { login, getUserData, user, logOut, loading } = useAuth();
async function onSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
try {
const user = await login("john@email.com", "password");
console.log(user);
} catch (err) {
console.log(err);
}
}
useEffect(() => {
getData(); //如果用户已登录,这将打印用户数据;如果未登录,将打印未找到用户
}, [user]);
async function getData() {
await getUserData();
}
return (
<div>
<form onSubmit={onSubmit}>
<button type="submit" disabled={loading}>登录</button>
</form>
<br />
{user && JSON.stringify(user)}
<br />
<button onClick={getUserData}>获取数据</button>
<br />
<button onClick={logOut}>注销</button>
</div>
);
};
要获取更多信息,您可以查看firebase文档以处理用户数据,还可以查看此存储库。
英文:
As @samthecodingman suggested, we should not use compact libraries for new projects.Here’s one example with the new modular Firebase API.
I had one context based example : Here Data component is wrapped inside AuthProvider in App.tsx:
AuthProvider.tsx:
import {
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
signOut,
User,
} from "firebase/auth";
import { doc, getDoc } from "firebase/firestore";
import React from "react";
import { auth, db } from "../config/firebase";
type ContextType = {
user: User | null;
loading: boolean;
login: (email: string, password: string) => Promise<User>;
register: (email: string, password: string) => Promise<User>;
logOut: () => Promise<void>;
getUserData: () => Promise<void>
};
const AuthContext = React.createContext({} as ContextType);
export function useAuth() {
return React.useContext(AuthContext);
}
export const AuthProvider = ({ children }: React.PropsWithChildren) => {
const [currentUser, setCurrentUser] = React.useState<User | null>(null);
const [loading, setLoading] = React.useState(true);
async function login(email: string, password: string) {
const userCredential = await signInWithEmailAndPassword(auth, email, password);
return userCredential.user;
}
async function register(email: string, password: string) {
const userCredential = await createUserWithEmailAndPassword(auth, email, password);
return userCredential.user;
}
async function getUserData() {
if(auth.currentUser) {
console.log("User: ", auth.currentUser);
const userRef = doc(db, "users", auth.currentUser?.uid);
const data = await getDoc(userRef);
if(!data.exists()) console.log("Not Found");
else console.log("User Data Found: ", data.data());
}else console.log("User Not Found");
}
function logOut() {
return signOut(auth);
}
React.useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((user) => {
setCurrentUser(user);
setLoading(false);
});
return unsubscribe;
}, []);
const value = {
user: currentUser,
loading: loading,
login: login,
register: register,
logOut: logOut,
getUserData: getUserData
};
return (
<AuthContext.Provider value={value}>
{!loading && children}
</AuthContext.Provider>
);
};
Data.tsx:
import { useEffect } from "react";
import { useAuth } from "./contexts/AuthProvider";
export default function Data() {
const { login, getUserData, user, logOut, loading} = useAuth();
async function onSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
try{
const user = await login("john@email.com", "password");
console.log(user);
}catch(err){
console.log(err);
}
}
useEffect(() => {
getData(); //If user Logged in this will print UserData If not will print User Not Found
}, [user])
async function getData() {
await getUserData();
}
return (
<div>
<form onSubmit={onSubmit}>
<button type="submit" disabled={loading}>Login</button>
</form>
<br />
{user && JSON.stringify(user)}
<br />
<button onClick={getUserData}>Get Data</button>
<br />
<button onClick={logOut}>Logout</button>
</div>
);
};
For more information you can follow firebase documentation for handling users data and also take a look at this repo
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论