Firebase身份验证延迟刷新 [英] firebase auth delayed on refresh

查看:169
本文介绍了Firebase身份验证延迟刷新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的SPA React / Firebase应用程序上进行硬刷新不会在立即执行某个功能时保持身份验证状态。我有一个解决方法,但它粗略。

我的反应路线利用 onEnter 函数来判断用户是否被认证。例如

 < Route path =/ securecomponent = {Dashboard} onEnter = {requireAuth} /> 

另外,我的 requireAuth 函数看起来像这样:

$ p $ function(nextState,replace){
console.log('requireAuth',firebase.auth()。当前用户);
if(!firebase.auth()。currentUser){
console.log('尝试访问安全路由,请先登录。
replace({
pathname:'/ login',
state:{nextPathname:nextState.location.pathname}
});
}
};

然而,在硬刷新上, firebase.auth稍有延迟().currentUser 。它首先是空的,然后执行 POST 到firebase服务器以确定auth状态。当它返回 currentUser 对象被填充。这个延迟会导致问题。



我的hacky解决方案如下: update:这实际上不工作...

  function(nextState,replace){
setTimeout(function(){
console.log('requireAuth',firebase.auth()。currentUser );
if(!firebase.auth()。currentUser){
console.log('试图访问一个安全的路由,请先登录');
replace({
pathname:'/ login',
state:{nextPathname:nextState.location.pathname}
});
}
},50);
};

只需在超时时间内包装即可。然而,我真的不喜欢这个...任何想法?
$ b $ p 更新:



我还试图将它封装在 onAuthStateChanged 侦听器中,它应该比 setTimeout 并有明确的时间延迟。代码如下:

  function(nextState,replace){
var unsubscribe = firebase.auth()。onAuthStateChanged功能(用户){
if(!user){
console.log('尝试访问安全路由');
replace({
pathname:'/ login' ,
state:{nextPathname:nextState.location.pathname}
})
console.log('should have called replace');
}
unsubscribe() ;
});
// setTimeout(function(){
// console.log('requireAuth',firebase.auth()。currentUser);
// if(!firebase.auth()。 );
//替换({
//路径名:'/ login',
// state:{nextPathname:nextState.location.pathname}
//});
//}
//},50);
};

执行两个日志语句,但react-router replace 似乎没有被正确执行。也许对于反应路由专家来说,这是一个不同的问题。

更新2:

<当我正在做这件事的时候,已经是深夜了。显然 setTimeout 实际上并不工作。

解决方案

好的。因此,我可以通过使用firebase提供的 localStorage 变量来解决这个问题,以存储用户信息。

$ p $ function(nextState,replace){
if(!firebase.auth()。currentUser){
让hasLocalStorageUser = false;
for(let key in localStorage){
if(key.startsWith(firebase:authUser:)){
hasLocalStorageUser = true;


if(!hasLocalStorageUser){
console.log('尝试访问安全路由,请先认证');
replace({
pathname:'/ login',
state:{nextPathname:nextState.location.pathname}
});
}
}
};


Hard refreshes on my SPA React/Firebase application does not maintain auth state on immediate execution of a function. I have a workaround, but it's sketchy.

My react routes utilize the onEnter function to determine whether or not the user is authenticated or not. For instance

<Route path="/secure" component={Dashboard} onEnter={requireAuth}/>

Furthermore, my requireAuth function looks like this:

function (nextState, replace) {
        console.log('requireAuth', firebase.auth().currentUser);
        if (!firebase.auth().currentUser) {
            console.log('attempting to access a secure route. please login first.');
            replace({
                pathname: '/login',
                state: { nextPathname: nextState.location.pathname }
            });
        }
};

However, on a hard refresh there is a slight delay on firebase.auth().currentUser. It's null at first, then executes a POST to firebase servers in order to determine auth state. When it returns the currentUser object is populated. This delay causes issues though.

My hacky solution is the following: update: this doesn't actually work...

function (nextState, replace) {
    setTimeout(function () {
        console.log('requireAuth', firebase.auth().currentUser);
        if (!firebase.auth().currentUser) {
            console.log('attempting to access a secure route. please login first.');
            replace({
                pathname: '/login',
                state: { nextPathname: nextState.location.pathname }
            });
        }
    }, 50);
};

Simply wrap it in a timeout. However, I really don't like this... any thoughts?

Update:

I have also tried to wrap it within a onAuthStateChanged listener, which should be more accurate than a setTimeout with a definitive time delay. Code as follows:

function (nextState, replace) {
    var unsubscribe = firebase.auth().onAuthStateChanged(function (user) {
        if (!user) {
            console.log('attempting to access a secure route');
            replace({
                pathname: '/login',
                state: { nextPathname: nextState.location.pathname }
            })
            console.log('should have called replace');
        }
        unsubscribe();
    });
    // setTimeout(function () {
    //     console.log('requireAuth', firebase.auth().currentUser);
    //     if (!firebase.auth().currentUser) {
    //         console.log('attempting to access a secure route. please login first.');
    //         replace({
    //             pathname: '/login',
    //             state: { nextPathname: nextState.location.pathname }
    //         });
    //     }
    // }, 50);
};

The two log statements are executed, but react-router replace does not seem to be executed correctly. Perhaps that's a different question for the react-router experts.

update 2:

It was late at night when I was working on this. Apparently setTimeout doesn't actually work either.

解决方案

Okay. So, I was able to solve this by utilizing the localStorage variable that firebase provides to store the user information.

function (nextState, replace) {
    if (!firebase.auth().currentUser) {
        let hasLocalStorageUser = false;
        for (let key in localStorage) {
            if (key.startsWith("firebase:authUser:")) {
                hasLocalStorageUser = true;
            }
        }
        if (!hasLocalStorageUser) {
            console.log('Attempting to access a secure route. Please authenticate first.');
            replace({
                pathname: '/login',
                state: { nextPathname: nextState.location.pathname }
            });
        }
    }
};

这篇关于Firebase身份验证延迟刷新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆