如何检测用户是否已登录 Firebase?

IT技术 javascript web firebase firebase-authentication
2021-03-05 11:05:03

我在我的 javascript 文件中使用 firebase 节点 api 进行 Google 登录。

firebase.initializeApp(config);
let provider = new firebase.auth.GoogleAuthProvider();
firebase.auth().signInWithPopup(provider);

这工作正常,用户可以使用他的 Google 凭据登录。当用户再次访问该页面时,弹出窗口再次打开,但由于他已经登录,弹出窗口将关闭,无需用户进行任何交互。有没有办法在提示弹窗之前检查是否已经有登录用户?

6个回答

https://firebase.google.com/docs/auth/web/manage-users

您必须添加一个身份验证状态更改观察者。

firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    // User is signed in.
  } else {
    // No user is signed in.
  }
});
是的,但不是通过onAuthStateChanged. 这是在 4.6.0 中添加的:firebase.google.com/support/release-notes/js#4.6.0您可以从登录方法或从currentUser.metadata(最后登录时间和创建时间)...
2021-04-16 11:05:03
这对我来说是不一致的。stackoverflow.com/questions/39395158/...
2021-04-26 11:05:03
这将检测其他选项卡上的登录事件。它按预期工作。Firebase 身份验证跨窗口传播登录事件。
2021-04-27 11:05:03
使用 onAuthStateChanged,有没有办法判断用户是否是新用户?
2021-05-12 11:05:03
@bojeil 我认为这种方法有一个警告。您可以将此代码放在一个页面上,即使您不在该页面上,它也会触发。它在 AuthState 更改时触发。如果它在其他页面上发生变化,您将在您不希望它时有效地触发它。至少,这就是我现在正在发生的事情。
2021-05-15 11:05:03

您还可以检查是否有currentUser

var user = firebase.auth().currentUser;

if (user) {
  // User is signed in.
} else {
  // No user is signed in.
}
这很奇怪,它对我有用,也许问题是因为 auth 是异步的并且 _ currentUser_ 尚未更新。
2021-04-18 11:05:03
你不能依赖它。请参阅官方文档:“在某些情况下,getCurrentUser 将返回非空值...”
2021-04-18 11:05:03
从文档中: currentUser 也可能为空,因为 auth 对象尚未完成初始化。如果您使用观察者来跟踪用户的登录状态,则不需要处理这种情况。
2021-04-24 11:05:03
即使在立即登录后,这也会为我返回 null。
2021-05-04 11:05:03
如果您得到 null,那可能是因为它还没有初始化。
2021-05-11 11:05:03

这是不可能的,告诉用户是否在页面开始加载签名,还有一个工作,虽然各地。

您可以将上次身份验证状态记忆到 localStorage 以在会话之间和选项卡之间保持它。

然后,当页面开始加载时,您可以乐观地假设用户将自动重新登录并将对话框推迟到您可以确定(即onAuthStateChanged触发之后)。否则,如果localStorage键为空,您可以立即显示对话框。

firebaseonAuthStateChanged事件将在页面加载后大约2 秒触发

// User signed out in previous session, show dialog immediately because there will be no auto-login
if (!localStorage.getItem('myPage.expectSignIn')) showDialog() // or redirect to sign-in page

firebase.auth().onAuthStateChanged(user => {
  if (user) {
    // User just signed in, we should not display dialog next time because of firebase auto-login
    localStorage.setItem('myPage.expectSignIn', '1')
  } else {
    // User just signed-out or auto-login failed, we will show sign-in form immediately the next time he loads the page
    localStorage.removeItem('myPage.expectSignIn')

    // Here implement logic to trigger the login dialog or redirect to sign-in page, if necessary. Don't redirect if dialog is already visible.
    // e.g. showDialog()
  }
})



我将它与Reactreact-router 一起使用我将上面的代码放入componentDidMount我的 App 根组件中。在那里,在渲染中,我有一些PrivateRoutes

<Router>
  <Switch>
    <PrivateRoute
      exact path={routes.DASHBOARD}
      component={pages.Dashboard}
    />
...

这就是我的 PrivateRoute 的实现方式:

export default function PrivateRoute(props) {
  return firebase.auth().currentUser != null
    ? <Route {...props}/>
    : localStorage.getItem('myPage.expectSignIn')
      // if user is expected to sign in automatically, display Spinner, otherwise redirect to login page.
      ? <Spinner centered size={400}/>
      : (
        <>
          Redirecting to sign in page.
          { location.replace(`/login?from=${props.path}`) }
        </>
      )
}

    // Using router Redirect instead of location.replace
    // <Redirect
    //   from={props.path}
    //   to={{pathname: routes.SIGN_IN, state: {from: props.path}}}
    // />
@hego64 你真的退出了你的 firebase 应用程序吗?此解决方案不进行登录。如果用户未在上一个会话中退出,它只允许跳过登录表单。/ 编辑:您是否处于重定向循环中?我会更新答案。
2021-04-17 11:05:03
是的,我应该更清楚,我被困在重定向循环中。我会注销,而不是返回应用程序,而是直接返回到登录页面。我能够通过回滚到以前的部署来修复它,但除此之外,我不确定如何解决该问题。
2021-04-23 11:05:03
@hego64 未登录的用户不应该能够自由走动,所以重定向到登录页面是正确的,但如果有未经身份验证的可用路由,则必须将逻辑移动到路由器或特定的路由,就像在我的 PrivateRoute 包装器示例中一样。因此,如果用户在受限制的页面上并退出,那么他们将被重定向到登录页面。您的其他路线不会实现此逻辑。
2021-04-27 11:05:03
我被困在这个有点......这个方法效果很好。谢谢你。
2021-04-28 11:05:03
你觉得你能帮我解决这个问题吗?我尝试了您在答案顶部的自动登录重定向,现在我似乎无法将其删除。我已经完全清除了我的本地存储,但由于不断的重定向,我仍然无法访问我注销的 firebase 站点。
2021-05-13 11:05:03

在这种情况下不需要使用 onAuthStateChanged() 函数。

您可以通过执行以下命令轻松检测用户是否已登录:

var user = firebase.auth().currentUser;

对于那些面临“返回空值”问题的人,这只是因为您没有等待 firebase 调用完成。

假设您在页面 A 上执行登录操作,然后调用页面 B,在页面 B 上您可以调用以下 JS 代码来测试预期的行为:

  var config = {
    apiKey: "....",
    authDomain: "...",
    databaseURL: "...",
    projectId: "..",
    storageBucket: "..",
    messagingSenderId: ".."
  };
  firebase.initializeApp(config);

    $( document ).ready(function() {
        console.log( "testing.." );
        var user = firebase.auth().currentUser;
        console.log(user);
    });

如果用户已登录,则“var user”将包含预期的 JSON 有效负载,如果没有,则为“null”

这就是你所需要的。

问候

@毛里西奥·西尔维斯特是吗?firebase.auth.currentUser无论我是否登录,使用返回未定义。只有 auth() 在登录时返回正确的结果。
2021-05-11 11:05:03

另一种方法是使用与 firebase 相同的东西。

例如,当用户登录时,firebase 将以下详细信息存储在本地存储中。当用户返回页面时,firebase 使用相同的方法来确定用户是否应该自动登录。

在此处输入图片说明

ATTN:因为 Firebase 既未列出也未推荐此方法。您可以将此方法称为非官方方式。这意味着以后如果 firebase 更改其内部工作,则此方法可能不起作用。或者简而言之。使用风险自负!:)