客户端屏幕在管理员用户登录应用程序时会短暂显示。

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

Client screen showing briefly when admin user signs in to app

问题

我有两个用户,一个是管理员,另一个是客户,所以当我以管理员身份登录时,我希望立即显示管理员界面,当我以客户身份登录时显示客户界面,但当我以管理员身份登录时,我仍然可以看到客户界面几秒钟,然后将我带到管理员界面,当我注销时,我回到客户界面而不是登录界面。

登录界面代码:

const SignIn = ({navigation}) => {

    const [email, setEmail] = React.useState('')
    const [password, setPassword] = React.useState('')

    useEffect(()=>{
        const unsubscribe = auth.onAuthStateChanged(user =>{
            if(user){
                navigation.navigate('Tabs')
                setEmail('')
                setPassword('')
            }
        })
        return unsubscribe
    },[])

应用界面代码:

const App = ({navigation}) => {

    const [user, setUser] = React.useState(null) // 当前用户
    const [users, setUsers] = React.useState([]) // 其他用户

    useEffect(() => {
        const unsubscribe = auth.onAuthStateChanged(async user => {
            if (user) {

                const userData = await db.collection("users").doc(user.uid).get();
                setUser(userData.data());

            } else {
                setUser(null);
            }
        });
        return () => unsubscribe();
    }, [])



    return (
        <NavigationContainer independent={true}>
            {user?.role === 'admin'? (<AdminNavi />):(<UserNavi/>)}
        </NavigationContainer>
    );
}

export default App;

我觉得我的代码结构可能不正确,因为如果你看应用界面的代码,我在那里重复使用了 useEffect,并且将条件放在了导航器容器之间。如果你们中的任何人可以帮忙重新组织我的代码,我将不胜感激。

英文:

I have two users, one is admin and the other client, so when I login as admin I want to display admin screen immediately and also when I login as client display client screen but login as admin I still can see client screen for few seconds then take me to the admin screen and when I logout I go back to client screen not login screen

Login screen code:

const SignIn = ({navigation}) =&gt; {

    const [email, setEmail] = React.useState(&#39;&#39;)
    const [password, setPassword] = React.useState(&#39;&#39;)

      useEffect(()=&gt;{
        const unsubscribe = auth.onAuthStateChanged(user =&gt;{
            if(user){
                navigation.navigate(&#39;Tabs&#39;)
                setEmail()
                setPassword()
            }
        })
        return unsubscribe
    },[])

App screen code:

const  App = ({navigation}) =&gt; {

      const [user, setUser] = React.useState(null) // This user
      const [users, setUsers] = React.useState([]) // Other Users
      
    
      useEffect(() =&gt; {
          const unsubscribe = auth.onAuthStateChanged(async user =&gt; {
              if (user) {
    
                  const userData = await db.collection(&quot;users&quot;).doc(user.uid).get();
                  setUser(userData.data());
               
                  
              } else {
                  setUser(null);
              }
          });
          return () =&gt; unsubscribe();
      }, [])
    
    
     
    
      
      return (
        &lt;NavigationContainer independent={true}&gt;
          {user?.role === &#39;admin&#39;? (&lt;AdminNavi /&gt;):(&lt;UserNavi/&gt;)}
        &lt;/NavigationContainer&gt;
      );
    }
    
    export default App;

I feel like I'm not structure the code correctly, because If you look at app screen code I'm repeating the use Effect again and I put the condition between Container Navigator. Please guys anyone of you can Re-structure my code is highly appreciated.

答案1

得分: 1

以下是已翻译的部分:

My best guess is that those few seconds are when you're loading the user data from Firestore. This may take some time, and you'll need to decide what you want to display during that time.

The simplest fix is to set the user to null while you're loading their data from Firestore:

useEffect(() => {
    const unsubscribe = auth.onAuthStateChanged(async user => {
        if (user) {
            setUser(null); // 🤷‍♂️;

            const userData = await db.collection("users").doc(user.uid).get();
            setUser(userData.data());
        } else {
            setUser(null);
        }
    });
    return () => unsubscribe();
}, [])

This will work, but causes the app to temporarily show the login screen while you're loading the data. If that is not acceptable, you'll want to introduce another state variable for while you're loading the user profile from Firestore:

useEffect(() => {
    const unsubscribe = auth.onAuthStateChanged(async user => {
        if (user) {
            setLoadingUser(true); // 🤷‍♂️;

            const userData = await db.collection("users").doc(user.uid).get();
            setLoadingUser(false); // 🤷‍♂️;
            setUser(userData.data());
        } else {
            setUser(null);
        }
    });
    return () => unsubscribe();
}, [])

And then you'd use the loadUser state property to render a "Loading user profile..." type indicator.

英文:

My best guess is that those few seconds are when you're loading the user data from Firestore. This may take some time, and you'll need to decide what you want to display during that time.

The simplest fix is to set the user to null while you're loading their data from Firestore:

  useEffect(() =&gt; {
      const unsubscribe = auth.onAuthStateChanged(async user =&gt; {
          if (user) {
              setUser(null); // &#128072;

              const userData = await db.collection(&quot;users&quot;).doc(user.uid).get();
              setUser(userData.data());
          } else {
              setUser(null);
          }
      });
      return () =&gt; unsubscribe();
  }, [])

This will work, but causes the app to temporarily show the login screen while you're loading the data. If that is not acceptable, you'll want to introduce another state variable for while you're loading the user profile from Firestore:

  useEffect(() =&gt; {
      const unsubscribe = auth.onAuthStateChanged(async user =&gt; {
          if (user) {
              setLoadingUser(true); // &#128072;

              const userData = await db.collection(&quot;users&quot;).doc(user.uid).get();
              setLoadingUser(false); // &#128072;
              setUser(userData.data());
          } else {
              setUser(null);
          }
      });
      return () =&gt; unsubscribe();
  }, [])

And then you'd use the loadUser state property to render a "Loading user profile..." type indicator.

huangapple
  • 本文由 发表于 2023年2月8日 09:39:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/75380618.html
匿名

发表评论

匿名网友

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

确定