【问题标题】:Firebase Authentication - How do I structure my react native app?Firebase 身份验证 - 如何构建我的反应原生应用程序?
【发布时间】:2020-06-05 10:58:37
【问题描述】:

希望你们都平安。

我的应用目前使用 React Navigation 5.0 在屏幕之间导航的这种方式:

首先,当身份验证状态发生变化时,它会这样做:

firebase.auth().onAuthStateChanged(user => {
            if (user) {
                this.setState({ isLoggedIn: true })
            } else {
                this.setState({ isLoggedIn: false })
            }
        })

然后,如果用户已登录,则会显示 AppStack,否则将显示 AuthStack,即登录和注册屏幕。

render() {
        return (
            <NavigationContainer>
                {this.state.loading ? (<LoadingScreen />) : this.state.isLoggedIn ? (<AppStack />) : (<AuthStack />)}
            </NavigationContainer>
        )
    }
function AuthStack() {
    return (
        <Stack.Navigator>
            <Stack.Screen name="LoginReg" component={LoginScreen} options={{ headerShown: false }} />
        </Stack.Navigator>)
}

function AppStack() {
    return (
        <Tab.Navigator
            screenOptions={({ route }) => ({
                tabBarIcon: ({ focused, color, size }) => {
                    if (route.name === 'Order') {
                        return (
                            <IconWithBadge
                                name={focused ? 'ios-book' : 'ios-book'}
                                size={size}
                                color={color}
                            />
                        );
                    } else if (route.name === 'Map') {
                        return (
                            <Ionicons
                                name={focused ? 'md-globe' : 'md-globe'}
                                size={size}
                                color={color}
                            />
                        );
                    } else if (route.name === 'Profile') {
                        return (
                            <Ionicons
                                name={focused ? 'md-contact' : 'md-contact'}
                                size={size}
                                color={color}
                            />
                        )
                    } else if (route.name === 'Notifications') {
                        return (
                            <Ionicons
                                name={focused ? 'ios-notifications-outline' : 'ios-notifications-outline'}
                                size={size}
                                color={color}
                            />
                        )
                    }
                },
            })}
            tabBarOptions={{
                activeTintColor: 'orange',
                inactiveTintColor: 'gray',
            }}>
            <Tab.Screen name="Order" component={OrderScreen} />
            <Tab.Screen name="Map" component={MapScreen} />
            <Tab.Screen name="Profile" component={ProfileScreen} />
            <Tab.Screen name="Notifications" component={Notifications} />
        </Tab.Navigator>)
}

现在,当用户注册时,firebase 会对用户进行身份验证并自动登录。因此,在我设法向 Firestore 发送有关用户出生日期等的一些数据之前,注册屏幕会卸载。

我在网上查了很多文章和文档,但我仍然不知道处理这种情况的最有效方法是什么,以便我也可以在注册屏幕卸载之前运行一些代码。

我这样做总体上是正确的还是完全错误的?任何帮助深表感谢。提前谢谢你。

【问题讨论】:

  • 是什么导致注册屏幕卸载?
  • firebase.auth().onAuthStateChanged(user => { if (user) { this.setState({ isLoggedIn: true }) } else { this.setState({ isLoggedIn: false }) } } ) 这会导致将 isLoggedIn 状态设置为 true,然后它会挂载 AppStack,正如您从我在帖子中的代码中看到的那样
  • 不会导致卸载。这只是更新isLoggedIn 的状态。一定是其他地方导致卸载?
  • 我猜你isLoggedIn的状态改变了视图?
  • 在render函数中可以看到我有this.state.isLoggedIn ? (&lt;AppStack /&gt;) : (&lt;AuthStack /&gt;)

标签: reactjs firebase react-native react-navigation


【解决方案1】:

我认为你需要做的是setState之后进行异步调用

所以您需要发出一个异步请求(同时可以显示加载屏幕),然后在完成后将状态设置为新视图。

【讨论】:

  • 感谢您的回答。但是我在不同的 .js 文件中有注册屏幕和登录屏幕。我该怎么做?
  • 在不同的文件里没关系。将它们分开的好方法。您在哪里使用 DoB 数据调用 firebase?
  • 是的,向 authstack 传递一个函数,该函数在请求完成后更新父组件状态,然后呈现您想要的新视图
  • 这不是hacky,如果你使用react with提升状态和传递函数来设置上面的状态,这是正确的方法。如果您的状态失控,您总是可以使用 redux 或其他状态管理框架来控制它
  • 不用担心。如果有帮助,请将答案标记为正确 :) 如果您遇到其他问题,您可以随时询问其他人,我很乐意提供帮助!
【解决方案2】:

你可以在你的状态下只拥有第二个属性,比如userDataSent,它也需要是true才能显示AppStack

然后你只设置userDataSent,一旦你知道你已经在你的服务器上发送/接收了数据。

您可以将userDataSent 存储为true 或AsyncStorage 中的其他内容,并在应用程序从冷加载时检索它,并每次自动更新您的状态。

可能是最简单的方法来适应你所拥有的!

【讨论】:

  • 嘿,谢谢你的回答 :) 事情是我在不同的 .js 文件中有我的登录和注册屏幕。那我怎么能做到呢?此外,您认为我的方式是一种相对有效的方式,还是有其他明显更好的方式来处理此注册、登录和应用程序视图?
  • 您对它们位于不同文件中的担忧是什么?两个文件都不需要知道isLoggedInuserDataSent。父组件正在决定是否显示它们。这就是它当前在您的代码中的工作方式,您只需要添加第二个条件来显示 AppStack,即this.state.isLoggedIn &amp;&amp; this.state.userDataSent。至于效率,我自己没有使用过 React Navigation,所以我不是专家......我唯一的问题是你有多确定你总是想要这种行为(即卸载 AppStack 而不是显示错误消息或东西)。
  • 不用担心它们在不同的文件中。但是userDataSent 变量将出现在注册屏幕中,因为它是 Register 函数所在的位置,并且只会在 Register.js 文件中将其设置为 true,而 Register.js 是子组件。父组件可以读取子组件变量吗?另外,我也不确定哈哈。我也是 React Navigation 的新手
  • 啊,我明白了。所以你需要把状态放在父组件中。然后你在父级中创建一个函数来改变它,比如onRegister = () =&gt; this.setState({userDataSent: true})。然后将该函数作为道具传递给 Register 子组件,例如 onRegister={this.onRegister},然后您可以像 this.props.onRegister() 一样在 Register 组件中调用它。简单:)
  • 非常感谢,非常感谢。现在它是有道理的! :)
猜你喜欢
  • 2019-02-23
  • 1970-01-01
  • 2021-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-01
  • 2017-10-11
  • 1970-01-01
相关资源
最近更新 更多