为了账号安全,请及时绑定邮箱和手机立即绑定

登录时从用户集合中获取用户数据

登录时从用户集合中获取用户数据

30秒到达战场 2023-08-18 14:20:07
我目前正在开发一个在客户端初始化了 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>  )}我主要担心的是每次刷新应用程序时都会获取用户的数据。任何有关此事的建议或最佳实践将不胜感激
查看完整描述

1 回答

?
忽然笑

TA贡献1806条经验 获得超5个赞

恕我直言,您使用上下文 API 和身份验证观察者的方法已经很好,只有一些小问题:

  • 你应该取消订阅你的观察者,正如 Awran5 提到的那样

  • 您可以观察用户数据,而不是只获取一次

  • 您可以将上下文分开以提高可读性和性能

  • 您可以使用所有者的 id 在集合 users 中创建文档,这样您就可以直接访问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>;

}

您的组件仍将在身份验证状态更改或用户数据更改时重新呈现,但仅在需要时重新呈现。


查看完整回答
反对 回复 2023-08-18
  • 1 回答
  • 0 关注
  • 110 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信