Firebase onAuthStateChange 是不是应该自动触发页面重定向?
Posted
技术标签:
【中文标题】Firebase onAuthStateChange 是不是应该自动触发页面重定向?【英文标题】:Is Firebase onAuthStateChange supposed to automatically trigger a page redirect?Firebase onAuthStateChange 是否应该自动触发页面重定向? 【发布时间】:2019-10-24 06:27:41 【问题描述】:我的应用需要在用户登录时执行一系列 Redux 调度。这些调度必须在用户被重定向到基于商店状态的页面之前完成。通过一些调试,我发现似乎在用户登录并触发 Firebase 的 onAuthStateChanged 侦听器后,页面会自动将用户重定向到登录页面(然后由 react-router 重定向)而不是当我声明重定向时。 有没有办法防止这种行为?
起初,我认为重定向是由调度触发的,但经过一些调试后,我将行为范围缩小到身份验证更改。一旦用户已经通过身份验证并执行页面刷新,我就可以验证一切是否按预期工作。
// A bunch of imports before this
const store = configureStore()
const jsx = (
<Provider store=store>
<AppRouter />
</Provider>
)
let hasRendered = false
const renderApp = () =>
if (!hasRendered)
store.dispatch(setApi()).then(() =>
ReactDOM.render(jsx, document.getElementById('app'))
)
hasRendered = true
ReactDOM.render(<LoadingPage />, document.getElementById('app'))
firebase.auth().onAuthStateChanged(async (user) =>
if (user)
console.log('logged in')
store.dispatch(login(user.uid))
await store.dispatch(startGetProfiles(user.uid))
const profiles = store.getState().profiles
const selectedCharacterId = localStorage.getItem('selectedCharacterId')
const profileId = selectedCharacterId || profiles.length === 1 && profiles[0].id
if (profileId)
await store.dispatch(startSetProfile(user.uid, profileId))
const profile = store.getState().profile
renderApp()
if (!!profile.id)
history.push('/profile')
else if (profiles.length > 0)
history.push('/select')
else
history.push('/create')
else
console.log('logged out')
store.dispatch(logout())
renderApp()
history.push('/')
)
我希望页面重定向仅在我使用 history.push('/somepage') 时发生,但重定向会在用户登录后立即触发。
【问题讨论】:
“Firebase onAuthStateChange 是否应该自动触发页面重定向?”没有。它不是,也不是。如果您在if (user)
上设置断点,当您在调试器中运行代码时会触发它吗?如果是这样,当您逐步执行该方法的其余部分时,哪一行没有按照您的预期执行?
Welp,我刚刚学会了如何实际调试,非常感谢。在深入研究之后,似乎页面刷新是在store.dispatch(login(user.uid))
调用之后立即发生的。此外,事实证明 else 块中的 history.push('/')
调用不是必需的,因为页面在 store.dispatch(logout())
调用之后重定向,这似乎加强了我的怀疑,即 firebase 在执行登录/注销后触发页面刷新过程。
这不太可能,但当然也不是不可能。您可以尝试在 jsbin 之类的网站上仅使用 Firebase 身份验证 SDK 重现它,以便我看看吗?请参阅how to create a minimal, complete, verifiable example,了解有关最小化重现问题所需代码的更多提示,以及为什么这很重要。
【参考方案1】:
好的,这就是我学到的东西 - 似乎正在发生的事情是,当我的路线中的道具发生变化时,正在发生刷新。我的所有路线如下所示:
export const PrivateRoute = (
isAuthenticated,
component: Component,
...rest
) => (
<Route ...rest component=(props) => (
isAuthenticated ? (
<Component ...props />
) : (
<Redirect to="/" />
)
) />
)
const mapStateToProps = (state) => (
isAuthenticated: !!state.auth && !!state.auth.uid
)
export default connect(mapStateToProps)(PrivateRoute)
请注意我是如何使用 Redux 在路由用户之前检查用户是否经过身份验证的。当向我的商店发送登录/注销操作的调用更新 auth 值时,这会更新 isAuthenticated
的路由属性,从而触发组件和路由链的更新。为了解决这个问题,我基本上必须创建新路由来处理路由器在更新时所做的事情,并从我的onAuthStateChanged
代码中删除history.push()
调用。
所以要回答我的问题,Firebase 不会触发页面重定向。将 Redux 与 React-Router 结合使用时,请注意路由道具的更改可能会触发组件更新和重新路由发生。
【讨论】:
以上是关于Firebase onAuthStateChange 是不是应该自动触发页面重定向?的主要内容,如果未能解决你的问题,请参考以下文章
firebase.auth().onAuthStateChanged 不工作
如何从 firebase.auth().onAuthStateChanged 中提取数据
.onAuthStateChanged 方法是不是计入 Firebase 身份验证验证?
TypeError: firebase.auth(...).onAuthStateChanged 不是函数