我想知道这是否真的是使用 onAuthStateChanged 的正确方法
I wonder if this really is the correct way to use onAuthStateChanged
关注这个react-firestore-tutorial
和 GitHub code。我想知道以下使用 onAuthStateChanged
的方法是否正确,或者我是否理解了这个不正确的方法,我只是很困惑这是否是正确的方法。
CodeSandBox 使用带有 apikey 的测试帐户完全连接到 Firebase!!所以你可以试试我的意思,我可以学习这个。
(注意:Firebase 正在阻止 Codesandbox url,即使它在授权域中,很抱歉,但您仍然可以看到代码)
t {code: "auth/too-many-requests", message: "We have blocked all
requests from this device due to unusual activity. Try again later.",
a: null}a:
请注意,这是一个仅使用 Reactjs-Vanilla 的完全成熟的高级网站;
反应 16.6
反应路由器 5
火力地堡 7
在代码中 Firebase.js
有这个 onAuthStateChanged
并且它从两个不同的组件调用并且多次调用,据我所知,应该只设置一次然后监听它的回调.多次调用它不会创建很多听众吗?
谁能看看这段代码在 Reactjs 中是否正常处理 onAuthStateChanged
?
(src\components\Firebase\firebase.js)
import app from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
class Firebase {
constructor() {
app.initializeApp(config);
.......
}
.....
onAuthUserListener = (next, fallback) =>
this.auth.onAuthStateChanged(authUser => {
if (authUser) {
this.user(authUser.uid)
.get()
.then(snapshot => {
const dbUser = snapshot.data();
// default empty roles
if (!dbUser.roles) {
dbUser.roles = {};
}
// merge auth and db user
authUser = {
uid: authUser.uid,
email: authUser.email,
emailVerified: authUser.emailVerified,
providerData: authUser.providerData,
...dbUser,
};
next(authUser);
});
} else {
fallback();
}
});
user = uid => this.db.doc(`users/${uid}`);
}
export default Firebase;
这两个rect-higher-order组件:
首先withAuthentication
:
(src\components\Session\withAuthentication.js)
import React from 'react';
import AuthUserContext from './context';
import { withFirebase } from '../Firebase';
const withAuthentication = Component => {
class WithAuthentication extends React.Component {
constructor(props) {
super(props);
this.state = {
authUser: JSON.parse(localStorage.getItem('authUser')),
};
}
componentDidMount() {
this.listener = this.props.firebase.onAuthUserListener(
authUser => {
localStorage.setItem('authUser', JSON.stringify(authUser));
this.setState({ authUser });
},
() => {
localStorage.removeItem('authUser');
this.setState({ authUser: null });
},
);
}
componentWillUnmount() {
this.listener();
}
render() {
return (
<AuthUserContext.Provider value={this.state.authUser}>
<Component {...this.props} />
</AuthUserContext.Provider>
);
}
}
return withFirebase(WithAuthentication);
};
export default withAuthentication;
和withAuthorization
:
(src\components\Session\withAuthorization.js)
import React from 'react';
import { withRouter } from 'react-router-dom';
import { compose } from 'recompose';
import AuthUserContext from './context';
import { withFirebase } from '../Firebase';
import * as ROUTES from '../../constants/routes';
const withAuthorization = condition => Component => {
class WithAuthorization extends React.Component {
componentDidMount() {
this.listener = this.props.firebase.onAuthUserListener(
authUser => {
if (!condition(authUser)) {
this.props.history.push(ROUTES.SIGN_IN);
}
},
() => this.props.history.push(ROUTES.SIGN_IN),
);
}
componentWillUnmount() {
this.listener();
}
render() {
return (
<AuthUserContext.Consumer>
{authUser =>
condition(authUser) ? <Component {...this.props} /> : null
}
</AuthUserContext.Consumer>
);
}
}
return compose(
withRouter,
withFirebase,
)(WithAuthorization);
};
export default withAuthorization;
这是正常的。 onAuthStateChanged
接收一个观察者函数,如果 sign-in 成功,则将用户对象传递给该观察者函数,否则不成功。
作者用高阶函数包装了 onAuthStateChanged
– onAuthUserListener
。 HOF 接收两个参数作为函数,next
和 fallback
。这两个参数是创建 HOC 时的唯一区别 withAuthentication
和 withAuthorization
.
前者的next
参数是将用户数据存储到localStorage的函数
localStorage.setItem('authUser', JSON.stringify(authUser));
this.setState({ authUser });
而后者的next
参数根据条件重定向到新路由。
if (!condition(authUser)) {
this.props.history.push(ROUTES.SIGN_IN);
}
所以,我们只是根据不同的需求传递不同的观察者函数。我们将用来包装我们的 HOC 的组件将在实例化时获得它们各自的观察者函数。观察者功能根据身份验证状态更改事件提供不同的功能。因此,回答你的问题,它是完全有效的。
参考:
关注这个react-firestore-tutorial
和 GitHub code。我想知道以下使用 onAuthStateChanged
的方法是否正确,或者我是否理解了这个不正确的方法,我只是很困惑这是否是正确的方法。
CodeSandBox 使用带有 apikey 的测试帐户完全连接到 Firebase!!所以你可以试试我的意思,我可以学习这个。
(注意:Firebase 正在阻止 Codesandbox url,即使它在授权域中,很抱歉,但您仍然可以看到代码)
t {code: "auth/too-many-requests", message: "We have blocked all requests from this device due to unusual activity. Try again later.", a: null}a:
请注意,这是一个仅使用 Reactjs-Vanilla 的完全成熟的高级网站;
反应 16.6
反应路由器 5
火力地堡 7
在代码中 Firebase.js
有这个 onAuthStateChanged
并且它从两个不同的组件调用并且多次调用,据我所知,应该只设置一次然后监听它的回调.多次调用它不会创建很多听众吗?
谁能看看这段代码在 Reactjs 中是否正常处理 onAuthStateChanged
?
(src\components\Firebase\firebase.js)
import app from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
class Firebase {
constructor() {
app.initializeApp(config);
.......
}
.....
onAuthUserListener = (next, fallback) =>
this.auth.onAuthStateChanged(authUser => {
if (authUser) {
this.user(authUser.uid)
.get()
.then(snapshot => {
const dbUser = snapshot.data();
// default empty roles
if (!dbUser.roles) {
dbUser.roles = {};
}
// merge auth and db user
authUser = {
uid: authUser.uid,
email: authUser.email,
emailVerified: authUser.emailVerified,
providerData: authUser.providerData,
...dbUser,
};
next(authUser);
});
} else {
fallback();
}
});
user = uid => this.db.doc(`users/${uid}`);
}
export default Firebase;
这两个rect-higher-order组件:
首先withAuthentication
:
(src\components\Session\withAuthentication.js)
import React from 'react';
import AuthUserContext from './context';
import { withFirebase } from '../Firebase';
const withAuthentication = Component => {
class WithAuthentication extends React.Component {
constructor(props) {
super(props);
this.state = {
authUser: JSON.parse(localStorage.getItem('authUser')),
};
}
componentDidMount() {
this.listener = this.props.firebase.onAuthUserListener(
authUser => {
localStorage.setItem('authUser', JSON.stringify(authUser));
this.setState({ authUser });
},
() => {
localStorage.removeItem('authUser');
this.setState({ authUser: null });
},
);
}
componentWillUnmount() {
this.listener();
}
render() {
return (
<AuthUserContext.Provider value={this.state.authUser}>
<Component {...this.props} />
</AuthUserContext.Provider>
);
}
}
return withFirebase(WithAuthentication);
};
export default withAuthentication;
和withAuthorization
:
(src\components\Session\withAuthorization.js)
import React from 'react';
import { withRouter } from 'react-router-dom';
import { compose } from 'recompose';
import AuthUserContext from './context';
import { withFirebase } from '../Firebase';
import * as ROUTES from '../../constants/routes';
const withAuthorization = condition => Component => {
class WithAuthorization extends React.Component {
componentDidMount() {
this.listener = this.props.firebase.onAuthUserListener(
authUser => {
if (!condition(authUser)) {
this.props.history.push(ROUTES.SIGN_IN);
}
},
() => this.props.history.push(ROUTES.SIGN_IN),
);
}
componentWillUnmount() {
this.listener();
}
render() {
return (
<AuthUserContext.Consumer>
{authUser =>
condition(authUser) ? <Component {...this.props} /> : null
}
</AuthUserContext.Consumer>
);
}
}
return compose(
withRouter,
withFirebase,
)(WithAuthorization);
};
export default withAuthorization;
这是正常的。 onAuthStateChanged
接收一个观察者函数,如果 sign-in 成功,则将用户对象传递给该观察者函数,否则不成功。
作者用高阶函数包装了 onAuthStateChanged
– onAuthUserListener
。 HOF 接收两个参数作为函数,next
和 fallback
。这两个参数是创建 HOC 时的唯一区别 withAuthentication
和 withAuthorization
.
前者的next
参数是将用户数据存储到localStorage的函数
localStorage.setItem('authUser', JSON.stringify(authUser));
this.setState({ authUser });
而后者的next
参数根据条件重定向到新路由。
if (!condition(authUser)) {
this.props.history.push(ROUTES.SIGN_IN);
}
所以,我们只是根据不同的需求传递不同的观察者函数。我们将用来包装我们的 HOC 的组件将在实例化时获得它们各自的观察者函数。观察者功能根据身份验证状态更改事件提供不同的功能。因此,回答你的问题,它是完全有效的。
参考: