reactjs - 在 React 中何时何地检查 Firebase 用户
问题描述
我想弄清楚如何使用 Firebase。
我有一个带有身份验证侦听器的配置:
onAuthUserListener(next, fallback) {
// onUserDataListener(next, fallback) {
return this.auth.onAuthStateChanged(authUser => {
if (!authUser) {
// user not logged in, call fallback handler
fallback();
return;
}
this.user(authUser.uid).get()
.then(snapshot => {
let snapshotData = snapshot.data();
let userData = {
...snapshotData, // snapshotData first so it doesn't override information from authUser object
uid: authUser.uid,
email: authUser.email,
emailVerified: authUser.emailVerifed,
providerData: authUser.providerData
};
setTimeout(() => next(userData), 0); // escapes this Promise's error handler
})
.catch(err => {
// TODO: Handle error?
console.error('An error occured -> ', err.code ? err.code + ': ' + err.message : (err.message || err));
setTimeout(fallback, 0); // escapes this Promise's error handler
});
});
}
// ... other methods ...
// }
我已阅读有关创建侦听器的文档以查看是否有 authUser 并已插入此身份验证侦听器。
import React from 'react';
import { AuthUserContext } from '../Session/Index';
import { withFirebase } from '../Firebase/Index';
const withAuthentication = Component => {
class WithAuthentication extends React.Component {
constructor(props) {
super(props);
this.state = {
authUser: null,
};
}
componentDidMount() {
this.listener = this.props.firebase.auth.onAuthStateChanged(
authUser => {
authUser
? this.setState({ 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;
然后在消费者组件中我有:
import React from 'react';
import {
BrowserRouter as Router,
Route,
Link,
Switch,
useRouteMatch,
} from 'react-router-dom';
import * as ROUTES from '../../constants/Routes';
import { compose } from 'recompose';
import { Divider, Layout, Card, Tabs, Typography, Menu, Breadcrumb, Icon } from 'antd';
import { withFirebase } from '../Firebase/Index';
import { AuthUserContext, withAuthorization, withEmailVerification } from '../Session/Index';
const { Title, Text } = Typography
const { TabPane } = Tabs;
const { Header, Content, Footer, Sider } = Layout;
const { SubMenu } = Menu;
class Dashboard extends React.Component {
state = {
collapsed: false,
loading: false,
};
onCollapse = collapsed => {
console.log(collapsed);
this.setState({ collapsed });
};
render() {
return (
<AuthUserContext.Consumer>
{ authUser => (
<div>
<Text style={{ float: 'right', color: "#fff"}}>
{/*
{
this.props.firebase.db.collection('users').doc(authUser.uid).get()
.then(doc => {
console.log( doc.data().name
)
})
}
*/}
</div>
)}
</AuthUserContext.Consumer>
);
}
}
export default withFirebase(Dashboard);
第一次加载页面时它工作正常。
但是,在页面刷新时,系统比代码慢并返回 null 错误消息,内容如下:
TypeError:无法读取 null 的属性“uid”(匿名函数)
我看过这篇文章,它提出了 Angular 的解决方案。
我找不到实现这一点的方法,以便它在反应中起作用。
文章建议:
firebase.auth().onAuthStateChanged( user =>; {
if (user) { this.userId = user.uid }
});
因此,在我的听众中,我尝试将 if 放在 authUser 前面 - 但这似乎不是一种有效的方法。
关于接下来要尝试什么来制作一个让firebase在运行检查之前加载用户的监听器有什么建议吗?
解决方案
试试react-with-firebase-auth这个库。
这个库为您提供了一个 withFirebaseAuth() 函数。
import * as React from 'react';
import * as firebase from 'firebase/app';
import 'firebase/auth';
import withFirebaseAuth, { WrappedComponentProps } from 'react-with-firebase-auth';
import firebaseConfig from './firebaseConfig';
const firebaseApp = firebase.initializeApp(firebaseConfig);
const App = ({
/** These props are provided by withFirebaseAuth HOC */
signInWithEmailAndPassword,
createUserWithEmailAndPassword,
signInWithGoogle,
signInWithFacebook,
signInWithGithub,
signInWithTwitter,
signInAnonymously,
signOut,
setError,
user,
error,
loading,
}: WrappedComponentProps) => (
<React.Fragment>
{
user
? <h1>Hello, {user.displayName}</h1>
: <h1>Log in</h1>
}
{
user
? <button onClick={signOut}>Sign out</button>
: <button onClick={signInWithGoogle}>Sign in with Google</button>
}
{
loading && <h2>Loading..</h2>
}
</React.Fragment>
);
const firebaseAppAuth = firebaseApp.auth();
/** See the signature above to find out the available providers */
const providers = {
googleProvider: new firebase.auth.GoogleAuthProvider(),
};
/** providers can be customised as per the Firebase documentation on auth providers **/
providers.googleProvider.setCustomParameters({hd:"mycompany.com"});
/** Wrap it */
export default withFirebaseAuth({
providers,
firebaseAppAuth,
})(App);
推荐阅读
- python - 在具有多个数字列的数据框中显示每个组的前 5 行
- azure - Azure WCF 服务可通过 WcfTestClient 访问,但不能通过浏览器或 MVC 站点访问
- vue.js - 在 Vue 中观察/观察 DOM 子节点的数量
- javascript - 在具有更好复杂性的对象数组中找到最佳团队
- kotlin - Kotlin 原生 readLine() 截断标准输入数据
- arrays - SwiftUI NavigationLink 不会显示动态数据
- access-token - Bot Framework Composer - 发布配置文件
- python - SyntaxError Line 18: TypeError: 'list' object is not callable
- javascript - 使用 ajax 将数组值从 PHP 传递到 JavaScript
- python - 如何查询父类上的两个子类的数据?(sqlalchemy)