Javascript 如何检测用户是否已登录Firebase?
我在谷歌登录的javascript文件中使用firebase节点apiJavascript 如何检测用户是否已登录Firebase?,javascript,web,firebase,firebase-authentication,Javascript,Web,Firebase,Firebase Authentication,我在谷歌登录的javascript文件中使用firebase节点api firebase.initializeApp(config); let provider = new firebase.auth.GoogleAuthProvider(); firebase.auth().signInWithPopup(provider); 这很好,用户可以使用他的谷歌凭证登录。当用户再次访问页面时,弹出窗口将再次打开,但由于用户已登录,弹出窗口将关闭,而无需用户进行任何交互。在提示弹出窗口之前,是否有方
firebase.initializeApp(config);
let provider = new firebase.auth.GoogleAuthProvider();
firebase.auth().signInWithPopup(provider);
这很好,用户可以使用他的谷歌凭证登录。当用户再次访问页面时,弹出窗口将再次打开,但由于用户已登录,弹出窗口将关闭,而无需用户进行任何交互。在提示弹出窗口之前,是否有方法检查是否已经有登录用户?使用Firebase.getAuth()
。它返回Firebase客户端的当前状态。否则返回值为null
以下是文档:
您必须添加身份验证状态更改观察者
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
} else {
// No user is signed in.
}
});
您还可以检查是否存在currentUser
首先导入以下内容
import Firebase
import FirebaseAuth
然后
在这种情况下,不需要使用onAuthStateChanged()函数 通过执行以下命令,您可以轻松检测用户是否已登录:
var user = firebase.auth().currentUser;
对于那些面临“返回null”问题的人来说,这只是因为您没有等待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”
这就是你所需要的
关于当页面开始加载时,不可能判断用户是否将被签名,但是有一个解决办法 您可以将上次身份验证状态记忆到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()
}
})
我将它与React和React路由器一起使用。我将上面的代码放入我的应用程序根组件的
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}}}
// />
导出默认函数PrivateRoute(props){
返回firebase.auth().currentUser!=null
?
:localStorage.getItem('myPage.expectSignIn')
//若预期用户自动登录,则显示微调器,否则重定向到登录页面。
?
: (
正在重定向到登录页面。
{location.replace(`/login?from=${props.path}`)}
)
}
//使用路由器重定向而不是location.replace
//
另一种方法是使用与firebase相同的东西
例如,当用户登录时,firebase会在本地存储中存储以下详细信息。
当用户返回页面时,firebase使用相同的方法确定用户是否应自动登录
收件人:因为firebase既没有列出也没有推荐。你可以把这种方法称为非官方的方法。这意味着,如果firebase稍后更改其内部工作,则此方法可能无法工作。或者简而言之。使用风险自负!:) 这是有效的:
异步函数IsLoggedIn():Promise{
试一试{
等待新的承诺((决定,拒绝)=>
app.auth().onAuthStateChanged(
用户=>{
如果(用户){
//用户已登录。
解析(用户)
}否则{
//没有用户登录。
拒绝('没有用户登录')
}
},
//防止控制台错误
错误=>拒绝(错误)
)
)
返回真值
}捕获(错误){
返回错误
}
}
如果您允许匿名用户以及通过电子邮件登录的用户,您可以使用
firebase.auth().currentUser.isAnonymous
,它将返回true
或false
,从技术上讲,承诺有三种可能性:
//1)最佳选项,因为它等待用户。。。
const isLoggedIn:any=等待新承诺((解决:any,拒绝:any)=>
this.afa.onAuthStateChanged((用户:any)=>
解析(用户),(e:any)=>拒绝(e));
console.log(isLoggedIn);
//2)可能会遇到注销状态问题。。。
const isLoggedIn2=等待this.afa.authState.pipe(first()).toPromise();
console.log(isLoggedIn2);
//3)在加载用户之前,技术上有第三个选项“未知”。。。
const isLoggedIn3=等待this.afa.currentUser;
console.log(isLoggedIn3);
//然后使用1、2或3执行类似操作(取决于您的需要):
如果(!!isLoggedIn){
//登录
}
另外请注意,该示例是有角度的,但您可以将
this.afa
替换为firebase.auth()
已弃用,请避免firebase.getAuth()
这对我来说是不一致的。使用onAuthStateChanged,是否有办法判断用户是否是新用户?是的,但不能通过onAuthStateChanged
。这是在4.6.0中添加的:您可以从登录方法或从currentUser.metadata
(上次登录时间和创建时间)获取它。@bojeil我认为此方法有一个警告。您可以将此代码放在一个页面上,即使您不在该页面上,它也会触发。当AuthState更改时,它将触发。如果它在其他页面上发生变化,当你不希望它发生变化时,它就会被触发。至少,我现在就是这样。这将在其他选项卡上检测登录事件。它按预期工作。Firebase Auth跨windows传播登录事件。即使在立即登录后,这也会为我返回null。这很奇怪,它对我有效,可能是因为Auth是异步的并且uCurrentUser_uuu尚未更新。从文档中可以看出:currentUser也可能为null,因为Auth
<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}}}
// />