获取当前用户与Firestore和React不起作用

huangapple go评论168阅读模式
英文:

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.

  1. import { useAuth } from "../../contexts/authContext";
  2. import firebase from "firebase/compat/app";
  3. import "firebase/compat/storage";
  4. import "firebase/compat/firestore";
  1. async function getUser() {
  2. const userRef = firestore
  3. .collection("users")
  4. .doc(firebase.auth().currentUser.uid);
  5. userRef.get().then(function (doc) {
  6. if (!doc.exists) {
  7. console.log("nothing");
  8. } else {
  9. console.log("document", doc.data().name);
  10. }
  11. });
  12. }
  13. useEffect(() => {
  14. getUser();
  15. }, [])

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.

  1. import { useAuth } from "../../contexts/authContext";
  2. import firebase from "firebase/compat/app";
  3. import "firebase/compat/storage";
  4. import "firebase/compat/firestore";
  1. async function getUser() {
  2. const userRef = firestore
  3. .collection("users")
  4. .doc(firebase.auth().currentUser.uid);
  5. userRef.get().then(function (doc) {
  6. if (!doc.exists) {
  7. console.log("nothing");
  8. } else {
  9. console.log("document", doc.data().name);
  10. }
  11. });
  12. }
  13. useEffect(() => {
  14. getUser();
  15. }, [])

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:

  1. import {
  2. createUserWithEmailAndPassword,
  3. signInWithEmailAndPassword,
  4. signOut,
  5. User,
  6. } from "firebase/auth";
  7. import { doc, getDoc } from "firebase/firestore";
  8. import React from "react";
  9. import { auth, db } from "../config/firebase";
  10. type ContextType = {
  11. user: User | null;
  12. loading: boolean;
  13. login: (email: string, password: string) => Promise<User>;
  14. register: (email: string, password: string) => Promise<User>;
  15. logOut: () => Promise<void>;
  16. getUserData: () => Promise<void>;
  17. };
  18. const AuthContext = React.createContext({} as ContextType);
  19. export function useAuth() {
  20. return React.useContext(AuthContext);
  21. }
  22. export const AuthProvider = ({ children }: React.PropsWithChildren) => {
  23. const [currentUser, setCurrentUser] = React.useState<User | null>(null);
  24. const [loading, setLoading] = React.useState(true);
  25. async function login(email: string, password: string) {
  26. const userCredential = await signInWithEmailAndPassword(auth, email, password);
  27. return userCredential.user;
  28. }
  29. async function register(email: string, password: string) {
  30. const userCredential = await createUserWithEmailAndPassword(auth, email, password);
  31. return userCredential.user;
  32. }
  33. async function getUserData() {
  34. if(auth.currentUser) {
  35. console.log("User: ", auth.currentUser);
  36. const userRef = doc(db, "users", auth.currentUser?.uid);
  37. const data = await getDoc(userRef);
  38. if(!data.exists()) console.log("Not Found");
  39. else console.log("User Data Found: ", data.data());
  40. } else console.log("User Not Found");
  41. }
  42. function logOut() {
  43. return signOut(auth);
  44. }
  45. React.useEffect(() => {
  46. const unsubscribe = auth.onAuthStateChanged((user) => {
  47. setCurrentUser(user);
  48. setLoading(false);
  49. });
  50. return unsubscribe;
  51. }, []);
  52. const value = {
  53. user: currentUser,
  54. loading: loading,
  55. login: login,
  56. register: register,
  57. logOut: logOut,
  58. getUserData: getUserData
  59. };
  60. return (
  61. <AuthContext.Provider value={value}>
  62. {!loading && children}
  63. </AuthContext.Provider>
  64. );
  65. };

Data.tsx:

  1. import { useEffect } from "react";
  2. import { useAuth } from "./contexts/AuthProvider";
  3. export default function Data() {
  4. const { login, getUserData, user, logOut, loading } = useAuth();
  5. async function onSubmit(e: React.FormEvent<HTMLFormElement>) {
  6. e.preventDefault();
  7. try {
  8. const user = await login("john@email.com", "password");
  9. console.log(user);
  10. } catch (err) {
  11. console.log(err);
  12. }
  13. }
  14. useEffect(() => {
  15. getData(); //如果用户已登录,这将打印用户数据;如果未登录,将打印未找到用户
  16. }, [user]);
  17. async function getData() {
  18. await getUserData();
  19. }
  20. return (
  21. <div>
  22. <form onSubmit={onSubmit}>
  23. <button type="submit" disabled={loading}>登录</button>
  24. </form>
  25. <br />
  26. {user && JSON.stringify(user)}
  27. <br />
  28. <button onClick={getUserData}>获取数据</button>
  29. <br />
  30. <button onClick={logOut}>注销</button>
  31. </div>
  32. );
  33. };

要获取更多信息,您可以查看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:

  1. import {
  2. createUserWithEmailAndPassword,
  3. signInWithEmailAndPassword,
  4. signOut,
  5. User,
  6. } from &quot;firebase/auth&quot;;
  7. import { doc, getDoc } from &quot;firebase/firestore&quot;;
  8. import React from &quot;react&quot;;
  9. import { auth, db } from &quot;../config/firebase&quot;;
  10. type ContextType = {
  11. user: User | null;
  12. loading: boolean;
  13. login: (email: string, password: string) =&gt; Promise&lt;User&gt;;
  14. register: (email: string, password: string) =&gt; Promise&lt;User&gt;;
  15. logOut: () =&gt; Promise&lt;void&gt;;
  16. getUserData: () =&gt; Promise&lt;void&gt;
  17. };
  18. const AuthContext = React.createContext({} as ContextType);
  19. export function useAuth() {
  20. return React.useContext(AuthContext);
  21. }
  22. export const AuthProvider = ({ children }: React.PropsWithChildren) =&gt; {
  23. const [currentUser, setCurrentUser] = React.useState&lt;User | null&gt;(null);
  24. const [loading, setLoading] = React.useState(true);
  25. async function login(email: string, password: string) {
  26. const userCredential = await signInWithEmailAndPassword(auth, email, password);
  27. return userCredential.user;
  28. }
  29. async function register(email: string, password: string) {
  30. const userCredential = await createUserWithEmailAndPassword(auth, email, password);
  31. return userCredential.user;
  32. }
  33. async function getUserData() {
  34. if(auth.currentUser) {
  35. console.log(&quot;User: &quot;, auth.currentUser);
  36. const userRef = doc(db, &quot;users&quot;, auth.currentUser?.uid);
  37. const data = await getDoc(userRef);
  38. if(!data.exists()) console.log(&quot;Not Found&quot;);
  39. else console.log(&quot;User Data Found: &quot;, data.data());
  40. }else console.log(&quot;User Not Found&quot;);
  41. }
  42. function logOut() {
  43. return signOut(auth);
  44. }
  45. React.useEffect(() =&gt; {
  46. const unsubscribe = auth.onAuthStateChanged((user) =&gt; {
  47. setCurrentUser(user);
  48. setLoading(false);
  49. });
  50. return unsubscribe;
  51. }, []);
  52. const value = {
  53. user: currentUser,
  54. loading: loading,
  55. login: login,
  56. register: register,
  57. logOut: logOut,
  58. getUserData: getUserData
  59. };
  60. return (
  61. &lt;AuthContext.Provider value={value}&gt;
  62. {!loading &amp;&amp; children}
  63. &lt;/AuthContext.Provider&gt;
  64. );
  65. };

Data.tsx:

  1. import { useEffect } from &quot;react&quot;;
  2. import { useAuth } from &quot;./contexts/AuthProvider&quot;;
  3. export default function Data() {
  4. const { login, getUserData, user, logOut, loading} = useAuth();
  5. async function onSubmit(e: React.FormEvent&lt;HTMLFormElement&gt;) {
  6. e.preventDefault();
  7. try{
  8. const user = await login(&quot;john@email.com&quot;, &quot;password&quot;);
  9. console.log(user);
  10. }catch(err){
  11. console.log(err);
  12. }
  13. }
  14. useEffect(() =&gt; {
  15. getData(); //If user Logged in this will print UserData If not will print User Not Found
  16. }, [user])
  17. async function getData() {
  18. await getUserData();
  19. }
  20. return (
  21. &lt;div&gt;
  22. &lt;form onSubmit={onSubmit}&gt;
  23. &lt;button type=&quot;submit&quot; disabled={loading}&gt;Login&lt;/button&gt;
  24. &lt;/form&gt;
  25. &lt;br /&gt;
  26. {user &amp;&amp; JSON.stringify(user)}
  27. &lt;br /&gt;
  28. &lt;button onClick={getUserData}&gt;Get Data&lt;/button&gt;
  29. &lt;br /&gt;
  30. &lt;button onClick={logOut}&gt;Logout&lt;/button&gt;
  31. &lt;/div&gt;
  32. );
  33. };

For more information you can follow firebase documentation for handling users data and also take a look at this repo

huangapple
  • 本文由 发表于 2023年3月7日 11:21:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/75657764.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定