So this problem I am facing for quite some time. Basically Registering user work to some extent. This is what is happening, upon the user being created and me getting the Auth token displayed in the dev-tools/Application and me being pushed to the home as I should.
When I refresh the page I get this error × Error: A cross-origin error was thrown. React doesn't have access to the actual error object in development. See https://reactjs.org/link/crossorigin-error for more information. I can fix this by clearing the localStorage. So if every time a new user is created, and if it wants to refresh the page, I will have to clear local storage every time. Which is totally not convenient.
There is another error, The logout handler is bugging, when I press the logout button it is displaying this error TypeError: Cannot read property 'push' of undefined and it pointing out the error is located in the UserContext. I would really appreciate some help really.
User Context
import React from "react";
import { useHistory } from "react-router-dom"
const UserContext = React.createContext();
function getUserFromLocalStorage() {
return localStorage.getItem("authToken")
? JSON.parse(localStorage.getItem("authToken"))
: { username: null, token: null };
}
function UserProvider({ children }) {
const [user, setUser] = React.useState(getUserFromLocalStorage());
const routerHistory = useHistory()
const logoutHandler = () =>{
localStorage.removeItem("authToken");
setUser(user);
routerHistory.push("/")
}
return (
<UserContext.Provider
value={{ user, setUser, logoutHandler }}
>
{children}
</UserContext.Provider>
);
}
export { UserContext, UserProvider };
Login
import React, { useState, } from "react";
import { useHistory } from "react-router-dom"
import axios from "axios";
import { Link } from "react-router-dom";
import "./Signin.css";
import { UserContext } from "../../context/user";
const Login = () => {
const { user, setUser } = React.useContext(UserContext);
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const history = useHistory()
const loginHandler = async (e) => {
e.preventDefault();
const config = {
header: {
"Content-Type": "application/json",
},
};
try {
const { data } = await axios.post(
"http://localhost:5000/api/auth/login",
{ email, password },
config
);
user.authToken = data.token;
setUser(user)
history.push("/");
} catch (error) {
if (error.response) {
setError(error.response.data.error);
}
setTimeout(() => {
setError("");
}, 5000);
}
};
return (
<div className="signin">
<Link to='/'>
<img src='/audible/logo.png' />
</Link>
<form onSubmit={loginHandler} className="form__container">
<h3>Sign in with your Amazon account</h3>
{error && <span className="error__message">{error}</span>}
<span className='labels'>Email </span>
<input
className="input__field"
type="email"
required
id="email"
onChange={(e) => setEmail(e.target.value)}
value={email}
tabIndex={1}
/>
<span className='signin__forgot'>Password{" "}
<Link className='links' to="/forgotpassword" >
Forgot Password?
</Link>
</span>
<input
className="input__field"
type="password"
required
id="password"
autoComplete="true"
onChange={(e) => setPassword(e.target.value)}
value={password}
tabIndex={2}
/>
<button type="submit" className="signin__btn">
Sign In
</button>
<span className='new__sign'>New to Amazon? </span>
<Link to="/register">
<button className='signin__register'>
Create your amazon account
</button>
</Link>
</form>
</div>
);
};
export default Login;
Register
import { useState, } from "react";
import axios from "axios";
import { Link } from "react-router-dom";
import { useHistory } from "react-router-dom"
const Register = () => {
const [username, setUsername] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [confirmpassword, setConfirmPassword] = useState("");
const [error, setError] = useState("");
const routerHistory = useHistory()
const registerHandler = async (e) => {
e.preventDefault();
const config = {
header: {
"Content-Type": "application/json",
},
};
if (password !== confirmpassword) {
setPassword("");
setConfirmPassword("");
setTimeout(() => {
setError("");
}, 5000);
return setError("Passwords do not match");
}
try {
const { data } = await axios.post(
"http://localhost:5000/api/auth/register",
{
username,
email,
password,
},
config
);
localStorage.setItem("authToken", data.token);
routerHistory.push('/login')
} catch (error) {
if (error.response) {
setError(error.response.data.error);
}
setTimeout(() => {
setError("");
}, 5000);
}
};
return (
<div className="signin">
<Link to='/'>
<img src='/audible/logo.png' />
</Link>
<form onSubmit={registerHandler} className="form__container">
<h3>Create account</h3>
{error && <span className="error__message">{error}</span>}
<span className='labels'>Username</span>
<input
type="text"
className="input__field"
required
id="name"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
<span className='labels'>Email</span>
<input
type="email"
className="input__field"
required
id="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<span className='labels'>Password</span>
<input
type="password"
required
id="password"
className="input__field"
autoComplete="true"
placeholder="At least 6 characters"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<span className='labels'>Re-enter password</span>
<input
type="password"
required
id="confirmpassword"
className="input__field"
autoComplete="true"
value={confirmpassword}
onChange={(e) => setConfirmPassword(e.target.value)}
/>
<button type="submit" className="register__btn">
Create your Amazon account
</button>
<span >
Already have an account? <Link className='links' to="/login">Login</Link>
</span>
</form>
</div>
);
};
export default Register;
Login Link
import React from "react";
import { Link, useHistory } from "react-router-dom";
import { CartContext } from "../../context/cart";
import { UserContext } from "../../context/user";
export default function LoginLink() {
const { user, logoutHandler } = React.useContext(UserContext);
const { clearCart } = React.useContext(CartContext);
if (user.authToken) {
return (
<button
onClick={() => {
logoutHandler();
clearCart()
}}
className="login-btn"
>
logout
</button>
);
}
return <Link to="/login">Signin</Link>;
}
Related
I am trying to upload signup data like image in firestore. I have setup firestore and storage in firebase although it gives this error.
"POST https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=AIzaSyAIAPVIvYAy4K20V5KgrEj4VESZ55ch6II 400"
what to do ? Can anyone please help?
My signup page:
import React, { useState } from "react";
import { Link } from "react-router-dom";
import { Container, Row, Col, Form, FormGroup } from "reactstrap";
import Helmet from "../components/Helmet/Helmet";
import { createUserWithEmailAndPassword, updateProfile } from "firebase/auth";
import { ref, uploadBytesResumable, getDownloadURL } from "firebase/storage";
import { setDoc, doc } from "firebase/firestore";
import { auth } from "../firebase.config";
import { storage } from "../firebase.config";
import { db } from "../firebase.config";
import { toast } from "react-toastify";
import "../styles/login.css";
const Signup = () => {
const [username, setUsername] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [file, setFile] = useState(null);
const [loading, setLoading] = useState(false);
const signupUser = async (e) => {
e.preventDefault();
setLoading(true);
try {
const userCredential = await createUserWithEmailAndPassword(
auth,
email,
password
);
const user = userCredential.user;
const storageRef = ref(storage, `images/${Date.now() + username}`);
const uploadTask = uploadBytesResumable(storageRef, file);
uploadTask.on(
(error) => {
toast.error(error.message);
},
() => {
getDownloadURL(updateProfile.snapshot.ref).then(
async (downloadURL) => {
await updateProfile(user, {
displayName: username,
photoURL: downloadURL,
});
await setDoc(doc(db, "users", user.uid), {
uid: user.uid,
displayName: username,
email,
photoURL: downloadURL,
});
}
);
}
);
} catch (error) {
toast.error("something went wrong");
}
};
return (
<Helmet title="Signup">
<section>
<Container>
<Row>
<Col lg="6" className="m-auto text-center">
<h3 className="fw-bold mb-2">Signup</h3>
<Form className="auth__form" onSubmit={signupUser}>
<FormGroup className="form__group">
<input
type="text"
placeholder="username"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
</FormGroup>
<FormGroup className="form__group">
<input
type="email"
placeholder="Enter your email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</FormGroup>
<FormGroup className="form__group">
<input
type="password"
placeholder="Password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</FormGroup>
<FormGroup className="form__group">
<input
type="file"
onChange={(e) => setFile(e.target.files[0])}
/>
</FormGroup>
<button type="submit" className="buy__btn auth__btn">
Create an account
</button>
<p>
Already have an account? <Link to="/login">Login</Link>
</p>
</Form>
</Col>
</Row>
</Container>
</section>
</Helmet>
);
};
export default Signup;
I think I have configured firebase correctly.
Trying to POST request to send data to database but it always shows 400 bad request.
The AuthReducer file is as follow. Data is not getting posted when done in Frontend but its properly working when tested in postman api.
export const Register = (username, email , password) => async(disptach) => {
try{
disptach({type:REGISTER_USER_REQUEST})
const config = {
Headers:{
'Content-Type':'application/json'
}
}
const { data } = await axios.post('/EShop/register', {username ,email , password} , config)
disptach({
type:REGISTER_USER_SUCCESS,
payload:data.user
})
}catch(error){
disptach({
type:REGISTER_USER_FAIL,
payload : error.response.data.message
})
}
}
The register form is as follow..
import React, { useState, useEffect } from "react";
import { Link, useNavigate } from "react-router-dom"
import { useSelector, useDispatch } from "react-redux"
import Loader from "./loader";
import { Register } from "../actions/UserAction";
import "../css-files/Account.css"
export default function register() {
const [email, setemail] = useState('');
const [password, setpassword] = useState('');
const [username, setusername] = useState('');
const disptach = useDispatch();
const navigate = useNavigate();
const { isAuthenticated, error, loading } = useSelector(state => state.user)
useEffect(() => {
if (isAuthenticated) {
navigate('/account/login')
}
}, [disptach, isAuthenticated])
const SubmitRegisterHandler = (e) => {
e.preventDefault()
disptach(Register(username, email, password))
}
return (
<div id="Account_container">
{loading ?
<Loader />
:
<div id="wrapper">
<div id="Wrap_First">
<img src="https://res.cloudinary.com/dqxozrie1/image/upload/v1659935744/eshop/online-registration-sign-up_gfb2gs.webp" />
</div>
<div id="Wrap_Second">
<div id="login">
<h2>Create New Account</h2>
<form onSubmit={SubmitRegisterHandler}>
<input
required
type="text"
placeholder="Username"
value={username}
onChange={(e) => { setusername(e.target.value) }}
/>
<input
required
type="email"
placeholder="Email"
value={email}
onChange={(e) => { setemail(e.target.value) }}
/>
<input
required
type="password"
placeholder="Password"
value={password}
onChange={(e) => { setpassword(e.target.value) }}
/>
<button>Register</button>
</form>
<p id="existing_acc"><Link to="/account/login">Already have an account !</Link></p>
</div>
</div>
</div>
}
</div>
);
}
It gives 400 bad request always. Please help me how to resolve this issue.
So here I have Login functionality via local storage token. I am getting the token upon user being created in The dev tools/Application. It is redirecting me to the home as it should. The thing that is not working is this. When I try to press the logout I am getting ×TypeError: Cannot read property 'push' of undefined it is showing the error in the Logout Handler function
Context Api
import React from "react";
import { useHistory } from "react-router-dom"
const UserContext = React.createContext();
function getUserFromLocalStorage() {
return localStorage.getItem("authToken")
? JSON.parse(localStorage.getItem("authToken"))
: { username: null, token: null };
}
function UserProvider({ children }) {
const [user, setUser] = React.useState(getUserFromLocalStorage());
const history = useHistory()
const logoutHandler = () =>{
localStorage.removeItem("authToken");
setUser(user);
history.push("/")
}
return (
<UserContext.Provider
value={{ user, setUser, logoutHandler }}
>
{children}
</UserContext.Provider>
);
}
export { UserContext, UserProvider };
Login Link
import React from "react";
import { Link } from "react-router-dom";
import { UserContext } from "../../context/user";
import { useHistory } from "react-router-dom"
export default function LoginLink() {
const { user, logoutHandler } = React.useContext(UserContext);
if (user.authToken) {
return (
<button
onClick={() => {
logoutHandler();
}}
className="login-btn"
>
logout
</button>
);
}
return <Link to="/login">login</Link>;
Header
import React from 'react';
import { Link, useHistory } from "react-router-dom";
import Search from './Search';
import './Header.css'
import SearchBooks from './SearchBooks';
import LoginLink from '../Signin/LoginLink';
import CartLink from '../Cart/CartLink';
import { UserContext } from '../../context/user';
const Header = () => {
const { user } = React.useContext(UserContext);
return (
<div className='header__container'>
<Link to='/'>
<img src='/audi.png' />
</Link>
<li>
<LoginLink />
</li>
{user.authToken &&(
<CartLink />
)
}
</div>
)
}
export default Header
Login
import { useState, } from "react";
import { useHistory } from "react-router-dom"
import axios from "axios";
import { Link } from "react-router-dom";
import "./Signin.css";
const Login = () => {
const { user, setUser } = React.useContext(UserContext);
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const history = useHistory()
const loginHandler = async (e) => {
e.preventDefault();
const config = {
header: {
"Content-Type": "application/json",
},
};
try {
const { data } = await axios.post(
"http://localhost:5000/api/auth/login",
{ email, password },
config
);
localStorage.setItem("authToken", data.token);
setUser(user)
history.push("/");
} catch (error) {
if (error.response) {
setError(error.response.data.error);
}
setTimeout(() => {
setError("");
}, 5000);
}
};
return (
<div className="login-screen">
<form onSubmit={loginHandler} className="login-screen__form">
<h3 className="login-screen__title">Login</h3>
{error && <span className="error-message">{error}</span>}
<div className="form-group">
<label htmlFor="email">Email:</label>
<input
type="email"
required
id="email"
placeholder="Email address"
onChange={(e) => setEmail(e.target.value)}
value={email}
tabIndex={1}
/>
</div>
<div className="form-group">
<label htmlFor="password">
Password:{" "}
<Link to="/forgotpassword" className="login-screen__forgotpassword">
Forgot Password?
</Link>
</label>
<input
type="password"
required
id="password"
autoComplete="true"
placeholder="Enter password"
onChange={(e) => setPassword(e.target.value)}
value={password}
tabIndex={2}
/>
</div>
<button type="submit" className="btn btn-primary">
Login
</button>
<span className="login-screen__subtext">
Don't have an account? <Link to="/register">Register</Link>
</span>
</form>
</div>
);
};
export default Login;
So here I have Login funcionality via local storage token. I am getting the token upon user being created in The dev tools/Application it is redirecting me to the home that is working. The thing that is not working is this. Creating an user it is working but when it loads it should show logout instead of login, and should hide the cart Component. Where am I making a mistake
Context Api
import React from "react";
const UserContext = React.createContext();
function getUserFromLocalStorage() {
return localStorage.getItem("authToken")
? JSON.parse(localStorage.getItem("authToken"))
: { username: null, token: null };
}
function UserProvider({ children }) {
const [user, setUser] = React.useState(getUserFromLocalStorage());
const history = useHistory();
const logoutHandler = () =>{
localStorage.removeItem("user");
history.push("/")
}
return (
<UserContext.Provider
value={{ user, logoutHandler }}
>
{children}
</UserContext.Provider>
);
}
export { UserContext, UserProvider };
Login Link
import React from "react";
import { Link } from "react-router-dom";
import { UserContext } from "../../context/user";
import { useHistory } from "react-router-dom"
export default function LoginLink() {
const { user, logoutHandler } = React.useContext(UserContext);
if (user.authToken) {
return (
<button
onClick={() => {
logoutHandler();
}}
className="login-btn"
>
logout
</button>
);
}
return <Link to="/login">login</Link>;
}
Header
import React from 'react';
import { Link, useHistory } from "react-router-dom";
import Search from './Search';
import './Header.css'
import SearchBooks from './SearchBooks';
import LoginLink from '../Signin/LoginLink';
import CartLink from '../Cart/CartLink';
import { UserContext } from '../../context/user';
const Header = () => {
const { user } = React.useContext(UserContext);
return (
<div className='header__container'>
<Link to='/'>
<img src='/audi.png' />
</Link>
<li>
<LoginLink />
</li>
{user.authToken &&(
<CartLink />
)
}
</div>
)
}
export default Header
Login Component
import { useState, } from "react";
import { useHistory } from "react-router-dom"
import axios from "axios";
import { Link } from "react-router-dom";
import "./Signin.css";
const Login = () => {
const { user, setUser } = React.useContext(UserContext);
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const history = useHistory()
const loginHandler = async (e) => {
e.preventDefault();
const config = {
header: {
"Content-Type": "application/json",
},
};
try {
const { data } = await axios.post(
"http://localhost:5000/api/auth/login",
{ email, password },
config
);
localStorage.setItem("authToken", data.token);
setUser(user)
history.push("/");
} catch (error) {
if (error.response) {
setError(error.response.data.error);
}
setTimeout(() => {
setError("");
}, 5000);
}
};
return (
<div className="login-screen">
<form onSubmit={loginHandler} className="login-screen__form">
<h3 className="login-screen__title">Login</h3>
{error && <span className="error-message">{error}</span>}
<div className="form-group">
<label htmlFor="email">Email:</label>
<input
type="email"
required
id="email"
placeholder="Email address"
onChange={(e) => setEmail(e.target.value)}
value={email}
tabIndex={1}
/>
</div>
<div className="form-group">
<label htmlFor="password">
Password:{" "}
<Link to="/forgotpassword" className="login-screen__forgotpassword">
Forgot Password?
</Link>
</label>
<input
type="password"
required
id="password"
autoComplete="true"
placeholder="Enter password"
onChange={(e) => setPassword(e.target.value)}
value={password}
tabIndex={2}
/>
</div>
<button type="submit" className="btn btn-primary">
Login
</button>
<span className="login-screen__subtext">
Don't have an account? <Link to="/register">Register</Link>
</span>
</form>
</div>
);
};
export default Login;
After you login, you have only set the authToken into your localStorage and not in your Provider. You'll need to call setUser after you login in order for Header component to know user is logged in.
I have a project where I'm using Firebase for the backend and ReactJS as the front end. I have successfully implemented the authentication and it's up and running but I can't seem to make my Firestore work. here is my fire.js file:
import firebase from 'firebase';
import "firebase/auth";
import "firebase/firestore";
if (!firebase.apps.length) {
var fire = firebase.initializeApp({
// my credentials //
});
}else {
fire = firebase.app(); // if already initialized, use that one
}
//const fire = firebase.initializeApp(firebaseConfig);
export default fire;
and here is the file in which I'm trying to add a contact document and then add name, email and message as fields:
import { BrowserRouter as Router, Route, Link} from "react-router-dom";
//import AddRecord from './AddRecord';
import * as FaIcons from "react-icons/fa";
import * as AiIcons from "react-icons/ai";
import { SidebarData } from './SidebarData';
//import { AddRecord } from './components/AddRecord';
import { IconContext } from 'react-icons';
import Button from 'react-bootstrap/Button';
import fire from "../fire";
const ContactUs = () => {
const [sidebar, setSidebar] = useState (false)
const showSidebar = () => setSidebar(!sidebar)
//const Hero handleLogout={handleLogout};
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [message, setMessage] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
fire.collection('contact').add({
name: name,
email: email,
message: message,
})
.then(() => {
alert("Thanks! We'll get back to you soon!");
})
.catch(error => {
alert(error.message);
})
setName("");
setEmail("");
setMessage("");
};
return (
<div>
<img src={croppped} className="mister" />
<IconContext.Provider value ={{color: '3e9e91'}}>
<div className="navbar">
<Link to ="#" className="menu-bars">
<FaIcons.FaBars onClick={showSidebar} />
</Link>
</div>
<nav className={sidebar ? 'nav-menu active' : 'nav-menu'}>
<ul className="nav-menu-items" onClick={showSidebar}>
<li className="navbar-toggle">
<Link to ="#" className="menu-bars">
<AiIcons.AiOutlineClose/>
</Link>
</li>
{SidebarData.map((item, index) => {
return (
<li key={index} className={item.cName}>
<Link to={item.path}>
{item.icon}
<span>{item.title}</span>
</Link>
</li>
)
})}
</ul>
</nav>
</IconContext.Provider>
<form className="form" onSubmit = {handleSubmit}>
<h1>Stuck Somewhere? Contact Us!</h1>
<input
placeholder="Enter Full Name"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<input placeholder="Enter Email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<textarea placeholder="Enter Message"
value={message}
onChange={(e) => setMessage(e.target.value)}>
</textarea>
<button type="submit">Submit</button>
</form>
</div>
)
}
export default ContactUs;
Your fire variable is the result of initializeApp, which is of type App. You need to call the firestore method to access the Firestore Service Interface:
fire.firestore().collection('contact')...