javascript - onAuthStateChanged 不一致

标签 javascript firebase firebase-authentication

当用户访问我的站点时,我使用 onAuthStateChanged确定用户是否已经从先前的 session 中登录。

主要问题是它对于一小部分用户来说是不一致的 - 代码似乎没有检测到他们确实有一个有效的登录 session 正在进行。

以下代码在应用程序本身上,用户在从主页或登录页面重定向后位于该页面上。

网站首页也使用onAuthStateChanged以确定是否应将用户直接重定向到应用程序。登录页面使用 signInWithEmailAndPassword ,当登录成功时,将它们重定向到应用程序页面(具有以下代码)。

firebase.auth().onAuthStateChanged(function (authUser) {
  if (authUser) return initApp(authUser);

  // issue: sometimes users that *should* be signed-in get signed in anonymously here
  firebase.auth().signInAnonymously().then(function (authUser) {
    initApp(authUser);
  }
});

onAuthStateChanged只是不应该用于我的用例吗?知道如何改进/解决这个问题吗?

编辑:这似乎更多地发生在手机用户身上。

最佳答案

我认为您没有按预期使用 onAuthStateChanged 。您不应该将其视为测试用户是否登录的一种方式。当您调用 onAuthStateChanged 时,您正在注册一个每次发生身份验证状态更改时都会调用的函数。

在我的应用程序(通常是 React 应用程序)中,onAuthStateChange 通常只在应用程序的主级别或最高级别内被调用一次。调用它来注册身份验证事件处理程序。然后,该事件处理函数响应身份验证状态的变化。如果处理函数传递了 null 的“用户”,表示没有用户通过身份验证,它会重定向到登录页面。如果调用处理程序函数并传递一个已设置的“用户”,它通常会在设置一些应用程序范围的用户详细信息后重定向到应用程序的主页或仪表板。

我的处理用户尝试登录的代码调用 Firebase 的一种登录方法来捕获(并处理)任何响应错误。它不使用“then”函数来响应成功的登录。它不需要。触发了身份验证状态更改事件,并且我使用 onAuthStateChanged 注册的事件处理函数被调用并处理重定向等。

如果您从应用程序中的多个不同位置调用 onAuthStateChanged,那么您实际上是在注册许多不同的处理程序函数,这些函数可能都响应身份验证状态更改。正如 bojeil 评论的那样,在您的示例中,您使用 onAuthStateChanged 注册的函数可以调用 signInAnonymously 函数......这将重新触发身份验证状态更改。用户永远无法真正退出,他们只是切换到匿名身份验证,这意味着他们总是以一种或另一种方式进行身份验证。也许这就是你想要的?我不确定当多个处理程序被注册并被触发时会发生什么。

我想还值得一提的是,您使用 onAuthStateChanged 注册的事件处理程序函数直到您的应用程序加载后才会被调用。您不能使用 onAuthStateChanged 作为同步方式来确定用户是否已通过身份验证,然后确定如何继续加载您的应用程序。作为一种解决方法,我的应用程序通常在本地存储中设置一个简单的标志,指示用户已通过身份验证。当应用程序加载时,在刷新或其他操作后,它会在本地存储中检查该身份验证标志,然后继续相应地加载。当 auth 状态更改处理程序触发时,应用程序的状态被验证为正确,或者,如果 auth 状态不同,应用程序会做出相应的 react 。

关于javascript - onAuthStateChanged 不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39395158/

相关文章:

javascript - 即使我使用 Number() 函数,数组的最后一个元素始终为 NaN

java - 如何仅在 Firebase 数据库发生更改时调用通知?

swift - 注册后如何/何时删除 Firebase Auth 监听器并写入数据库?

android - Firebase 电话身份验证检查是否触发了 reCAPTCHA 流程

javascript - 使用 jquery 验证条件时显示警报

javascript - iframe 中的 WKWebView 本地文件

javascript - 循环中的 Leaflet MarkerCluster bindPopup 仅使用最后一个值

java - 从 Firebase 获取 child 的名字?

ios - 搜索 firebase 数据 : iOS, Swift

android - 应用程序在 FirebaseAuth.DefaultInstance 之后崩溃