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

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

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

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

183098 次浏览

使用 Firebase.getAuth()。它返回 Firebase 客户端的当前状态。否则返回值为 null,这里是文档: https://www.firebase.com/docs/web/api/firebase/getauth.html

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.
}
});

您还可以检查是否有一个 CurrentUser

var user = firebase.auth().currentUser;


if (user) {
// User is signed in.
} else {
// No user is signed in.
}

首先导入以下内容

import Firebase
import FirebaseAuth

然后

    // Check if logged in
if (Auth.auth().currentUser != null) {
// User is logged in
}else{
// User is not logged in
}

在这个场景中不需要使用 onAuthStateChanged ()函数。

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

var user = firebase.auth().currentUser;

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

假设您在 Page A 上执行登录操作,然后调用 Page B,在 Page 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”

这就够了。

问候

它是 不可能,用来告诉用户在页面开始加载时是否对 威尔进行签名,不过还有一个工作要做。

可以将 记住最后的认证状态转换为 localStorage,以便在会话之间和制表符之间保持它。

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

在页面加载之后,firebase onAuthStateChanged事件将大致触发 两秒

// 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()
}
})



我使用这与 做出反应反应路由器。我将上面的代码放入 App root 组件的 componentDidMount中。那里,在渲染中,我有一些 PrivateRoutes

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

这就是我的私人路线是如何实现的:

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}}}
// />

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

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

enter image description here

火力点既没有列出,也没有推荐。您可以调用这个方法,这是非官方的方式。这意味着以后如果火力基地改变了他们的内部工作,这种方法可能不起作用。简而言之。使用风险自负!:)

这种方法是有效的:

async function IsLoggedIn(): Promise<boolean> {
try {
await new Promise((resolve, reject) =>
app.auth().onAuthStateChanged(
user => {
if (user) {
// User is signed in.
resolve(user)
} else {
// No user is signed in.
reject('no user logged in')
}
},
// Prevent console error
error => reject(error)
)
)
return true
} catch (error) {
return false
}
}

如果您允许匿名用户以及那些用电子邮件登录的用户,您可以使用 firebase.auth().currentUser.isAnonymous,它将返回 truefalse

从技术上讲,有三种可能性:

// 1) best option, as it waits on user...


const isLoggedIn: any = await new Promise((resolve: any, reject: any) =>
this.afa.onAuthStateChanged((user: any) =>
resolve(user), (e: any) => reject(e)));


console.log(isLoggedIn);


// 2) may experience logging out state problems...


const isLoggedIn2 = await this.afa.authState.pipe(first()).toPromise();


console.log(isLoggedIn2);


// 3) technically has a 3rd option 'unknown' before user is loaded...


const isLoggedIn3 = await this.afa.currentUser;


console.log(isLoggedIn3);




// then do something like (depending on your needs) with 1, 2, or 3:


if (!!isLoggedIn) {
// logged in
}


还要注意,这个例子是角形的,但是您可以用 firebase.auth()代替 this.afa

最新库版本的使用示例

import { initializeApp } from "firebase/app";
import { getAuth, onAuthStateChanged } from "firebase/auth";


const firebaseConfig = {
...
};


const app = initializeApp(firebaseConfig);
const auth = getAuth(app);


onAuthStateChanged(auth, user => {
if (user) {
// User is signed in.
} else {
// No user is signed in.
}
})

对于火库 v9.8.1和角度 v13.3.5,我不使用 AngularFire,然后我使用这个服务工作得很好。

@Injectable({providedIn: 'root'})
export class IsAuthenticatedGuard implements CanActivate {


canActivate(): Promise<boolean> {
return new Promise(resolve =>
onAuthStateChanged(getAuth(),
user => resolve(!!user),
_ => resolve(false)));
}


}