Javascript history.push()在firebase中不工作';用react进行验证
我正在使用react、firebase auth和contextapi构建身份验证 签名Javascript history.push()在firebase中不工作';用react进行验证,javascript,reactjs,firebase,firebase-authentication,Javascript,Reactjs,Firebase,Firebase Authentication,我正在使用react、firebase auth和contextapi构建身份验证 签名 import React, { useEffect, useState } from 'react'; import { Form, Button, Container, Card } from 'react-bootstrap'; import { useAuth } from '../contextApi/contextApi'; import { Link } from 'react-router-d
import React, { useEffect, useState } from 'react';
import { Form, Button, Container, Card } from 'react-bootstrap';
import { useAuth } from '../contextApi/contextApi';
import { Link } from 'react-router-dom';
import { useHistory } from 'react-router-dom';
function SignIn() {
let history = useHistory();
const { signIn } = useAuth();
const emailRef = React.useRef(null);
const passwordRef = React.useRef(null);
const [loading, setLoading] = useState(false);
let handleSubmit = async (e) => {
e.preventDefault();
console.log('connected');
try {
setLoading(true);
await signIn(emailRef.current.value, passwordRef.current.value);
console.log('push');
history.push('/dashboard');
} catch {
alert('handleSubmit went wrong!');
}
history.push('/dashboard');
setLoading(false);
};
return (
<div style={{ backgroundColor: '#a9a9a9' }}>
<Container
className="signin d-flex align-items-center justify-content-center"
style={{
minHeight: '100vh',
}}
>
<Card className="shadow">
<Card.Body>
<h2 className="text-center mb-4">Sign In</h2>
<Form onSubmit={handleSubmit}>
<Form.Group controlId="formBasicEmail">
<Form.Label>Email address</Form.Label>
<Form.Control
type="email"
placeholder="Enter email"
ref={emailRef}
required
/>
<Form.Text className="text-muted">
We'll never share your email with anyone else.
</Form.Text>
</Form.Group>
<Form.Group controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control
type="password"
placeholder="Password"
ref={passwordRef}
required
/>
</Form.Group>
<Button variant="primary" type="submit" disabled={loading}>
Submit
</Button>
</Form>
<div className="w-100 text-center mt-2">
Need an account? <Link to="/signup">Sign up</Link>
</div>
<div className="w-100 text-center mt-2">
Forgot password? <Link to="/forgotpassword">Click here</Link>
</div>
<div className="w-100 text-center mt-2">
Back to <Link to="/">Home page</Link>
</div>
</Card.Body>
</Card>
</Container>
</div>
);
}
export default SignIn;
import React,{useffect,useState}来自“React”;
从“react bootstrap”导入{Form,Button,Container,Card};
从“../contextApi/contextApi”导入{useAuth};
从'react router dom'导入{Link};
从'react router dom'导入{useHistory};
函数签名(){
让历史=使用历史();
const{signIn}=useAuth();
const emailRef=React.useRef(null);
const passwordRef=React.useRef(null);
const[loading,setLoading]=useState(false);
让handleSubmit=async(e)=>{
e、 预防默认值();
console.log('connected');
试一试{
设置加载(真);
等待登录(emailRef.current.value、passwordRef.current.value);
console.log('push');
history.push('/dashboard');
}抓住{
警报(“handleSubmit出错!”);
}
history.push('/dashboard');
设置加载(假);
};
返回(
登录
电子邮件地址
我们永远不会与其他人共享您的电子邮件。
密码
提交
需要账户吗?注册吧
忘记密码?点击这里
返回主页
);
}
导出默认签名;
只要我成功签约,一切都会顺利进行,
但若我登录失败,那个么以后即使我输入了正确的密码/电子邮件,登录页面也不会重定向到仪表板页面
有人能解释一下我的代码哪一部分是错的吗
contextApi.js
import React, { useContext, useEffect, useState } from 'react';
import { auth } from '../firebase';
import { useHistory } from 'react-router-dom';
const ContextApi = React.createContext();
export function useAuth() {
return useContext(ContextApi);
}
export const ContextApiProvider = ({ children }) => {
let [currentUser, setCurrentUser] = useState();
let [loading, setLoading] = useState(true);
useEffect(() => {
const unsubscribed = auth.onAuthStateChanged((user) => {
if (user) {
setCurrentUser(user);
setLoading(false);
} else {
setCurrentUser(null);
setLoading(false);
console.log(currentUser);
}
});
return unsubscribed;
}, []);
const signIn = (email, password) => {
auth.signInWithEmailAndPassword(email, password).catch(function (error) {
// Handle Errors here.
console.log(error);
let errorCode = error.code;
let errorMessage = error.message;
if (errorCode === 'auth/wrong-password') {
alert('sign in failed! Wrong password.');
} else if (!errorMessage) {
alert('you are signed in!');
} else {
alert(`sign in failed! ${errorMessage}`);
}
});
};
const signUp = (email, password) => {
auth.createUserWithEmailAndPassword(email, password).catch((error) => {
let errorCode = error.code;
let errorMessage = error.message;
console.log(errorMessage);
console.log(error);
console.log(errorCode);
if (errorCode === 'auth/weak-password') {
alert(`signup failed! The password is too weak!`);
} else if (!errorMessage) {
alert('signed up successfully');
} else {
alert(`sign up failed! ${errorMessage}`);
}
});
};
const resetPassword = (email) => {
auth.sendPasswordResetEmail(email).catch((error) => {
let errorCode = error.code;
let errorMessage = error.message;
if (errorCode === 'auth/invalid-email') {
alert('email not found');
} else {
alert(errorMessage);
}
});
};
const logout = () => {
return auth.signOut();
};
let value = {
signIn,
currentUser,
signUp,
resetPassword,
logout,
};
return (
<ContextApi.Provider value={value}>
{!loading && children}
{/* {children} */}
</ContextApi.Provider>
);
};
从“React”导入React,{useContext,useEffect,useState};
从“../firebase”导入{auth};
从'react router dom'导入{useHistory};
const ContextApi=React.createContext();
导出函数useAuth(){
返回useContext(ContextApi);
}
export const ContextApiProvider=({children})=>{
让[currentUser,setCurrentUser]=useState();
let[loading,setLoading]=useState(true);
useffect(()=>{
const unsubscribed=身份验证onAuthStateChanged((用户)=>{
如果(用户){
setCurrentUser(用户);
设置加载(假);
}否则{
setCurrentUser(空);
设置加载(假);
console.log(当前用户);
}
});
退订;
}, []);
const signIn=(电子邮件、密码)=>{
使用email和password(电子邮件、密码)进行身份验证登录。捕获(函数(错误){
//在这里处理错误。
console.log(错误);
设errorCode=error.code;
让errorMessage=error.message;
如果(错误代码==='auth/错误密码'){
警报('登录失败!密码错误');
}如果(!errorMessage),则为else{
警报('您已登录!');
}否则{
警报(`sign-in failed!${errorMessage}`);
}
});
};
const注册=(电子邮件、密码)=>{
auth.createUserWithEmailAndPassword(电子邮件,密码).catch((错误)=>{
设errorCode=error.code;
让errorMessage=error.message;
控制台日志(错误消息);
console.log(错误);
控制台日志(错误代码);
如果(错误代码==='auth/weak password'){
警报(`注册失败!密码太弱!`);
}如果(!errorMessage),则为else{
警报(“注册成功”);
}否则{
警报(`sign up failed!${errorMessage}`);
}
});
};
const resetPassword=(电子邮件)=>{
auth.sendPasswordResetEmail(email).catch((错误)=>{
设errorCode=error.code;
让errorMessage=error.message;
如果(错误代码=='auth/invalid email'){
警报(“未找到电子邮件”);
}否则{
警报(错误消息);
}
});
};
常量注销=()=>{
返回auth.signOut();
};
let值={
签名,
当前用户,
报名,
重置密码,
注销,
};
返回(
{!正在加载(&children}
{/*{children}*/}
);
};
您没有正确使用firebase函数,下面是您应该如何使用它的示例(来自文档)
虽然wait应该可以工作,但您无法确定用户是否已登录,上面的代码是另一种操作方式。
signIn
似乎没有返回任何值,也不是异步函数,因此不清楚您在handleSubmit
处理程序中等待了什么。你有两个历史记录。将推到你的仪表板上,你是说两个都不起作用吗?signin是contectApi.jsI中useAuth的一个函数。我知道,你把它作为一个片段包含在你的问题中,这就是为什么我知道它不是异步函数,也不返回任何东西,所以我很好奇为什么它在UI中是await
ed。它实际上是一个异步函数!让handleSubmit=async(e)=>{e.preventDefault();console.log('connected');try{…}你的意思是我应该处理history.push-ini在contectApi中删除我的登录函数吗?我已经尝试过了,但是我会得到这个错误!无法读取undefinedyes的属性“push”,因为您没有定义历史记录,所以您得到了该属性,您需要使用Router将其导入,并将其作为包装器(WithRouter(组件名称))、finay和props中的hostory({history,props2,Props3…})添加到中
const signIn = (email, password) => {
firebase.auth().signInWithEmailAndPassword(email, password)
.then((user) => {
// Signed in
//here you call history push (or a callback defined somone else)
// doc state that here we know that credentials was accepted
// while await means simply that the async code ended
// Then is better since you aren't blocking anything and it is more clean (most importantly people who maintain your code will have no issue)
// you will have no issue if firebase update something in thier lib ...
// history need to be defined before or passed as param
history.push('/dashboard')
// ...
})
.catch((error) => {
// nothing is required from you here (but you can for example show "forget password link)
var errorCode = error.code;
var errorMessage = error.message;
});
}