Problem with JS functions, using Firebase and React - javascript

thanks for your patience. I'm implementing Firebase on my site but when I call the signup function in FormUp.js (declared in AuthContext.js) it doesn't refer to the function definition. This causes the function called in FormUp.js, not to call its own function defined in AuthContext.js, but falls into the catch branch ('Failed to create an account'). I don't understand why. Hope someone can help me, thanks!
Error:
TypeError: _firebase__WEBPACK_IMPORTED_MODULE_1__.auth.createUserWithEmailAndPassword is not a function
at signup (bundle.js:4226:56)
at handleSubmit (bundle.js:2575:13)
at HTMLUnknownElement.callCallback (bundle.js:41062:18)
at Object.invokeGuardedCallbackDev (bundle.js:41111:20)
at invokeGuardedCallback (bundle.js:41171:35)
at invokeGuardedCallbackAndCatchFirstError (bundle.js:41186:29)
at executeDispatch (bundle.js:45421:7)
at processDispatchQueueItemsInOrder (bundle.js:45453:11)
at processDispatchQueue (bundle.js:45466:9)
at dispatchEventsForPlugins (bundle.js:45477:7)
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
at Navbar (http://localhost:3000/static/js/bundle.js:3361:76)
at Home
Code:
AuthContext.js
import React, { useContext, useState, useEffect } from "react";
import { auth } from "../firebase";
import { createUserWithEmailAndPassword } from "firebase/auth";
const AuthContext = React.createContext();
export function useAuth() {
return useContext(AuthContext);
}
export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState();
const [loading, setLoading] = useState(true);
function signup(email, password) {
return auth.createUserWithEmailAndPassword(email, password);
}
function login(email, password) {
return auth.signInWithEmailAndPassword(email, password);
}
function logout() {
return auth.signOut();
}
function resetPassword(email) {
return auth.sendPasswordResetEmail(email);
}
function updateEmail(email) {
return currentUser.updateEmail(email);
}
function updatePassword(password) {
return currentUser.updatePassword(password);
}
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((user) => {
setCurrentUser(user);
setLoading(false);
});
return unsubscribe;
}, []);
const value = {
currentUser,
login,
signup,
logout,
resetPassword,
updateEmail,
updatePassword,
};
return (
<AuthContext.Provider value={value}>
{!loading && children}
</AuthContext.Provider>
);
}
firebase.js
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
const firebaseConfig = {
//Hidden
};
const app = initializeApp(firebaseConfig);
const auth = getAuth();
export { app, auth };
FormUp.js
import React, { useRef, useState } from "react";
import { Link } from "react-router-dom";
import {
FormUser,
Input,
Label,
Subtitle,
TextWrapper,
TopLine,
FormButton,
Credentials,
HomePage,
SignInLink,
SignInText,
RedirectSignIn,
Credential,
} from "./Form.elements";
import { FaAngleLeft } from "react-icons/fa";
import { useAuth } from "../../contexts/AuthContext";
import { Alert } from "bootstrap";
const FormUp = ({
primary,
lightBg,
lightTopLine,
lightTextDesc,
buttonLabel,
description,
topLine,
}) => {
const emailRef = useRef();
const passwordRef = useRef();
const passwordConfirmRef = useRef();
const { signup } = useAuth();
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
async function handleSubmit(e) {
e.preventDefault();
if (passwordRef.current.value !== passwordConfirmRef.current.value) {
return setError("Password do not match");
}
try {
setError("");
setLoading(true);
await signup(emailRef.current.value, passwordRef.current.value);
} catch {
setError("Failed to create an account");
}
setLoading(false);
}
return (
<>
<style>
#import
url('https://fonts.googleapis.com/css2?family=Poppins:wght#100;200;300;400;500;600;700;800;900&display=swap');
</style>
<FormUser lightBg={lightBg} onSubmit={handleSubmit}>
<TextWrapper>
<HomePage href="/">
<FaAngleLeft />
<TopLine lightTopLine={lightTopLine}>{topLine}</TopLine>
</HomePage>
<Subtitle lightTextDesc={lightTextDesc}>{description}</Subtitle>
{error && (
<h5 style={{ color: "red", paddingBottom: "30px" }}>{error}</h5>
)}
<Credentials>
<Credential id="email">
<Label>Email</Label>
<Input
ref={emailRef}
required
type="email"
placeholder="Email..."
></Input>
</Credential>
<Credential id="password">
<Label>Password</Label>
<Input
ref={passwordRef}
required
type="password"
placeholder="Password..."
></Input>
</Credential>
<Credential id="password-confirm">
<Label>Password confirmation</Label>
<Input
ref={passwordConfirmRef}
required
type="password"
placeholder="Password confirmation..."
></Input>
</Credential>
</Credentials>
<FormButton disabled={loading} type="submit" big primary={primary}>
{buttonLabel}
</FormButton>
<RedirectSignIn>
<SignInText>Already have an account?</SignInText>
<SignInLink href="/sign-in">Log in</SignInLink>
</RedirectSignIn>
</TextWrapper>
</FormUser>
</>
);
};
export default FormUp;

Related

react doesn't update the data, only after reloading page

It is my Auth Login form. I have AuthContext. Let's try log in.
I've clicked "log in" button. And we see AuthContext "user" : underfind
Then click reload page, and here we go, we have logged in
Why does it work like that?
Login.js
import React, {useState} from 'react'
import {useLogin} from '../hooks/useLogin'
import { useNavigate } from 'react-router-dom'
const Login = () => {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const {login, error, isLoading} = useLogin()
let navigate = useNavigate()
const handleSubmit = async (e) => {
e.preventDefault()
await login(email, password)
}
return(
<div className='container'>
<h1>
login page
</h1>
<form className={'d-flex flex-column'} onSubmit={handleSubmit}>
<h3>Log in</h3>
<label>Email:</label>
<input
type={'email'}
onChange={(e) => setEmail(e.target.value)}
/>
<label>Password</label>
<input
type={'password'}
onChange={(e) => setPassword(e.target.value)}
/>
<button disabled={isLoading} type={'submit'}>
Log in
</button>
{error && <div className={'error'}>
{error}
</div>}
</form>
</div>
)
}
export default Login;
useLogin.js
import { useState } from "react";
import { useAuthContext } from "./useAuthContext";
export const useLogin = () => {
const [error, setError] = useState(null)
const [isLoading, setIsLoading] = useState(null)
const {dispatch} = useAuthContext()
const login = async (email, password) => {
setIsLoading(true)
setError(null)
const response = await fetch('/api/user/login', {
method:'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({email, password})
})
const json = await response.json()
if(!response.ok){
setIsLoading(false)
setError(json.error)
}
if(response.ok){
localStorage.setItem('user', JSON.stringify(json))
dispatch({type:'LOGIN', paylaod:json})
setIsLoading(false)
}
}
return {login, isLoading, error}
}
AuthContext.js
import { createContext, useReducer, useEffect } from "react";
export const AuthContext = createContext()
export const authReducer = (state, action) => {
switch(action.type){
case 'LOGIN':
return {user: action.payload}
case 'LOGOUT':
return {user:null}
default:
return state
}
}
export const AuthContextProvider = ({children}) => {
const [state, dispatch] = useReducer(authReducer, {
user:null
})
useEffect(() => {
const user = JSON.parse(localStorage.getItem('user'))
if(user){
dispatch({type:'LOGIN', payload: user})
}
}, [])
console.log('AuthContext state', state)
return(
<AuthContext.Provider value={{...state, dispatch}}>
{children}
</AuthContext.Provider>
)
}
useAuthContext.js
import { AuthContext } from "../context/AuthContext";
import { useContext } from "react";
export const useAuthContext = () => {
const context = useContext(AuthContext)
if(!context){
throw Error('useAuthContext must be used inside an AuthContextProvider')
}
return context
}
here is Navbar.js
import React from "react";
import { useAuthContext } from "../hooks/useAuthContext";
import { useLogout } from "../hooks/useLogout";
import { Link } from "react-router-dom";
const Nav = () => {
const {logout} = useLogout()
const {user} = useAuthContext()
const handleClick= () => {
logout()
}
return(
<div>
{user && (
<div className="bg-dark text-light align-item-center d-flex justify-content-between m-auto container-fluid p-2">
<span className="m-0 p-0 d-flex align-item-center">{user.email}</span>
<button className="btn btn-outline-danger" onClick={handleClick}>logout</button>
</div>
)}
{!user && (
<div className="d-flex justify-content-between">
<Link to='/'>
<button>HOME</button>
</Link>
<Link to='/login'>
<button>LOGIN</button>
</Link>
<Link to='/signup'>
<button>SIGNUP</button>
</Link>
</div>
)}
</div>
)
}
export default Nav
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { AuthContextProvider } from './context/AuthContext';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<AuthContextProvider>
<App />
</AuthContextProvider>
</React.StrictMode>
);
app.js
import {BrowserRouter, Routes, Route} from 'react-router-dom'
import Nav from './components/Nav';
import Home from './pages/home';
import Login from './pages/login';
import Signup from './pages/signup';
function App() {
return (
<div>
<BrowserRouter>
<Nav/>
<Routes>
<Route path={'/'} element={<Home/>}/>
<Route path={'/login'} element={<Login/>}/>
<Route path={'/signup'} element={<Signup/>}/>
</Routes>
</BrowserRouter>
</div>
);
}
export default App;
I don't think it is server error.
There's a spelling mistake in useLogin payload is written wrong
dispatch({type:'LOGIN', paylaod:json});
// Should be: Payload
dispatch({type:'LOGIN', payload:json});
The root cause seems to be a typo:
dispatch({type:'LOGIN', paylaod:json})
has a typo in paylaod, so the reducer's
case 'LOGIN':
return {user: action.payload}
basically just sets {user: undefined}.
You should add error checking to your reducer, or better yet switch to a typed language like TypeScript so typos like these are caught at type-check time.
Since the user is not in the component state, it will not re-render after it is set (which seems to happen after first rendering). Add a useEffect with dependency on the value that updates the state and it should be good. F.ex:
const Nav = () => {
const {contextUser} = useAuthContext()
const [user, setUser] = useState()
...
useEffect(() => {
if (contextUser) {
setUser(contextUser)
}
}, [contextUser])
...
}

Context provider not Rendering any Component inside <AuthProvider>Childern</AuthProvider>

I am New to React and the I am Using Context For First time, I am learning about Authentication with Firebase so I working on this SignUp Component. It was Working Fine Untill I put the Code between Context.Provider and React is not Rendering anything Inside it
I also tried creating test.jsx which return Text in div to see if my SignUp component is causing error but even test is not rendering
I tried to find other article but i cannot pinpoint issue in my Code
App.js
import React from 'react'
import SignUp from "./components/SignUp";
import {Container} from 'react-bootstrap'
import { AuthProvider } from "./context/AuthContext";
function App() {
return (
<AuthProvider>
<SignUp />
</AuthProvider>
);
}
export default App;
AuthContext.js
import React, { useContext, useEffect, useState } from 'react'
import { auth } from '../firebase'
const AuthContext = React.createContext()
export function useAuth() {
return useContext(AuthContext);
};
export function AuthProvider({ childern }) {
const [currentUser, setCurrentUser] = useState();
function signUp(email, password) {
return auth.createUserWithEmailAndPassword(email, password);
}
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged(user => {
setCurrentUser(user);
console.log(user)
});
return unsubscribe
},[])
const value = {
currentUser,
signUp
}
return (
<AuthContext.Provider value={value} >
{childern}
</AuthContext.Provider>
)
};
Btw SignUp is not Rendering at all It is blank page
SignUp.jsx
import React, { useRef, useState } from 'react'
import { Form, Card, Button, Alert } from 'react-bootstrap'
import { useAuth } from '../context/AuthContext';
export default function SignUp() {
const emailRef = useRef();
const passwordRef = useRef();
const passwordConfirmRef = useRef();
const { signUp } = useAuth();
const [error, setError] = useState('')
const [loading,SetLoading] = useState(false)
async function handleSubmit(e) {
e.preventDefault()
if (passwordRef.current.value !== passwordConfirmRef.current.value) {
return setError['Password do not Match']
}
try {
setError("")
SetLoading(true)
await signUp(emailRef.current.value, passwordRef.current.value)
} catch {
setError('Failed to Create an Account')
}
SetLoading(false)
}
return (
<>
<Card>
<Card.Body>
<h2 className='text-center mb-4'>Sign Up</h2>
{error && <Alert variant="danger" >
{error}
</Alert>}
<Form onSubmit={handleSubmit} >
<Form.Group id="email">
<Form.Label>Email</Form.Label>
<Form.Control type="email" ref={emailRef} required ></Form.Control>
</Form.Group>
<Form.Group id="password">
<Form.Label>Password</Form.Label>
<Form.Control type="password" ref={passwordRef} required ></Form.Control>
</Form.Group>
<Form.Group id="password-confrim">
<Form.Label>Password Confrimation</Form.Label>
<Form.Control type="password" ref={passwordConfirmRef} required ></Form.Control>
</Form.Group>
<Button
disbled={loading}
className="w-100 mt-2" type="submit" >Sign Up</Button>
</Form>
</Card.Body>
</Card>
<div className="w-100 text-center mt-2">
Already have an account? Log In
</div>
</>
)
}
React Dev Tools In Chrome
App -> AuthProvider -> Context.Provider
AuthProvider
Prop
{
"children": "<ForwardRef />"
}
Hooks
[
{
"name": "State",
"value": null
}
},
{
"name": "Effect",
"value": "ƒ () {}"
}
}
]
Context.Provider
Props
{
"value": {
"currentUser": null,
"signUp": "ƒ signUp() {}"
}
}
i have been trying to find solution but couldn't

setLoggedIn is not a function react

Okay I'm trying to use global states to store if an user is logged in or not. To do so, I've created a Context file as follows:
import { createContext } from "react";
export const LoginContext= createContext({})
I also have my App.jsx:
import React, { useState } from 'react';
import Component1 from './Component1.jsx';
import Component2 from './Component2.jsx';
import Component3 from './Component3.jsx';
import { LoginContext } from '../Helper/Context.js';
function App(){
const [loggedIn, setLoggedIn] = useState(false);
return (
<LoginContext.Provider value={{loggedIn, setLoggedIn}}>
<Component1 />
<Component2 />
<Component3 />
</LoginContext.Provider>
)
}
export default App;
And then I have my Login component:
import React, {useState, useContext} from "react";
import Axios from 'axios';
import { Link, useHistory } from 'react-router-dom';
import { LoginContext } from "../Helper/Context";
import NavbarHome from "./NavbarHome";
function Login()
{
Axios.defaults.withCredentials = true;
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [loginStatus, setLoginStatus] = useState(false);
const {loggedIn, setLoggedIn} = useContext(LoginContext);
const [error, setErrorStatus] = useState("");
let history = useHistory();
let user = {
id: null,
nombre: null,
email: null
};
const login = () => {
Axios.post('http://localhost:3001/login', {
email: email,
password: password,
}).then((response)=>{
if(!response.data.auth) {
setLoginStatus(false);
setErrorStatus(response.data.message)
setLoggedIn(false);
}
else{
localStorage.setItem("token", response.data.token)
user = {
id: response.data.result[0].id,
name: response.data.result[0].name,
email: response.data.result[0].email
}
setLoginStatus(true);
setLoggedIn(true);
history.push('/perfil');
}
});
};
const userAuthenticated = () => {
Axios.get("http://localhost:3001/isUserAuth", {
headers: {
"x-access-token": localStorage.getItem("token"),
},
}).then((response) => {
console.log(response);
});
}
return(
<div>
<div>
<NavbarHome />
<div>
<div>
<h1>Login</h1>
<p className="label-login">Email:</p>
<input type="text" placeholder="Email..." onChange={(event) => {setEmail(event.target.value);}}/>
<p className="label-login">Contraseña:</p>
<input type="password" placeholder="Password..." onChange={(event) => {setPassword(event.target.value);}}/> <br />
<button onClick={login}>Login</button>
<p style={{marginTop: '1.3rem', color: 'red'}}>{error}</p>
<p><Link to='/registro'>Register here!</Link></p>
</div>
</div>
</div>
</div>
);
}
export default Login;
The output that I receive is this:
It complains about the line where I do this: setLoggedIn(false); or setLoggedIn(true); I'd like to use that state instead of setLoginStatus (which is the one I'm currently using)
Any ideas on how to fix it?

JS functions error using Firebase and React

Thanks for your patience. I'm implementing Firebase on my site but when I call the signup function in FormUp.js (declared in AuthContext.js) it doesn't refer to the function definition. This causes the function called in FormUp.js, not to call its own function defined in AuthContext.js, but falls into the catch branch ('Failed to create an account'). I don't understand why. Hope someone can help me, thanks!
Error:
TypeError: _firebase__WEBPACK_IMPORTED_MODULE_1__.auth.createUserWithEmailAndPassword is not a function
at signup (bundle.js:4226:56)
at handleSubmit (bundle.js:2575:13)
at HTMLUnknownElement.callCallback (bundle.js:41062:18)
at Object.invokeGuardedCallbackDev (bundle.js:41111:20)
at invokeGuardedCallback (bundle.js:41171:35)
at invokeGuardedCallbackAndCatchFirstError (bundle.js:41186:29)
at executeDispatch (bundle.js:45421:7)
at processDispatchQueueItemsInOrder (bundle.js:45453:11)
at processDispatchQueue (bundle.js:45466:9)
at dispatchEventsForPlugins (bundle.js:45477:7)
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
at Navbar (http://localhost:3000/static/js/bundle.js:3361:76)
at Home
Code:
AuthContext.js
import React, { useContext, useState, useEffect } from "react";
import { auth } from "../firebase";
import { createUserWithEmailAndPassword } from "firebase/auth";
const AuthContext = React.createContext();
export function useAuth() {
return useContext(AuthContext);
}
export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState();
const [loading, setLoading] = useState(true);
function signup(email, password) {
return auth.createUserWithEmailAndPassword(email, password);
}
function login(email, password) {
return auth.signInWithEmailAndPassword(email, password);
}
function logout() {
return auth.signOut();
}
function resetPassword(email) {
return auth.sendPasswordResetEmail(email);
}
function updateEmail(email) {
return currentUser.updateEmail(email);
}
function updatePassword(password) {
return currentUser.updatePassword(password);
}
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((user) => {
setCurrentUser(user);
setLoading(false);
});
return unsubscribe;
}, []);
const value = {
currentUser,
login,
signup,
logout,
resetPassword,
updateEmail,
updatePassword,
};
return (
<AuthContext.Provider value={value}>
{!loading && children}
</AuthContext.Provider>
);
}
firebase.js
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
const firebaseConfig = {
//Hidden
};
const app = initializeApp(firebaseConfig);
const auth = getAuth();
export { app, auth };
FormUp.js
import React, { useRef, useState } from "react";
import { Link } from "react-router-dom";
import {
FormUser,
Input,
Label,
Subtitle,
TextWrapper,
TopLine,
FormButton,
Credentials,
HomePage,
SignInLink,
SignInText,
RedirectSignIn,
Credential,
} from "./Form.elements";
import { FaAngleLeft } from "react-icons/fa";
import { useAuth } from "../../contexts/AuthContext";
import { Alert } from "bootstrap";
const FormUp = ({
primary,
lightBg,
lightTopLine,
lightTextDesc,
buttonLabel,
description,
topLine,
}) => {
const emailRef = useRef();
const passwordRef = useRef();
const passwordConfirmRef = useRef();
const { signup } = useAuth();
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
async function handleSubmit(e) {
e.preventDefault();
if (passwordRef.current.value !== passwordConfirmRef.current.value) {
return setError("Password do not match");
}
try {
setError("");
setLoading(true);
await signup(emailRef.current.value, passwordRef.current.value);
} catch {
setError("Failed to create an account");
}
setLoading(false);
}
return (
<>
<style>
#import
url('https://fonts.googleapis.com/css2?family=Poppins:wght#100;200;300;400;500;600;700;800;900&display=swap');
</style>
<FormUser lightBg={lightBg} onSubmit={handleSubmit}>
<TextWrapper>
<HomePage href="/">
<FaAngleLeft />
<TopLine lightTopLine={lightTopLine}>{topLine}</TopLine>
</HomePage>
<Subtitle lightTextDesc={lightTextDesc}>{description}</Subtitle>
{error && (
<h5 style={{ color: "red", paddingBottom: "30px" }}>{error}</h5>
)}
<Credentials>
<Credential id="email">
<Label>Email</Label>
<Input
ref={emailRef}
required
type="email"
placeholder="Email..."
></Input>
</Credential>
<Credential id="password">
<Label>Password</Label>
<Input
ref={passwordRef}
required
type="password"
placeholder="Password..."
></Input>
</Credential>
<Credential id="password-confirm">
<Label>Password confirmation</Label>
<Input
ref={passwordConfirmRef}
required
type="password"
placeholder="Password confirmation..."
></Input>
</Credential>
</Credentials>
<FormButton disabled={loading} type="submit" big primary={primary}>
{buttonLabel}
</FormButton>
<RedirectSignIn>
<SignInText>Already have an account?</SignInText>
<SignInLink href="/sign-in">Log in</SignInLink>
</RedirectSignIn>
</TextWrapper>
</FormUser>
</>
);
};
export default FormUp;
Well, the problem here is, as the error message suggest, that auth does not have a property called createUserWithEmailAndPassword. What you are searching for is not part of auth. Your code should be something like
function signup(email, password) {
return createUserWithEmailAndPassword(auth, email, password);
}
instead of
function signup(email, password) {
return auth.createUserWithEmailAndPassword(email, password);
}
Check this (if you are using version 8 of the SDK, then you need to use a different approach)
https://firebase.google.com/docs/auth/web/password-auth#create_a_password-based_account
My suggestion is to add a linter to your project to easily catch these issues. In this case the issue would have been immediately visible since the import of createUserWithEmailAndPassword is not used.

Firebase sendPasswordResetEmail not working in React

I have tried to create password reset option to web app with firebase and Other firebase options are works fine like GoogleLogin and Email Sign Up, but when i try sendPasswordResetEmail it returns following error,
TypeError: firebase__WEBPACK_IMPORTED_MODULE_1_.auth.sendPasswordResetEmail is not a function
Here's the Code,
firebase.js
import { initializeApp } from "firebase/app";
import { getAuth, GoogleAuthProvider, signInWithPopup } from "firebase/auth";
const firebaseConfig = {
apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.REACT_APP_FIREBASE_APP_ID
};
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
export const provider = new GoogleAuthProvider();
export const signInWithGooglePopUp = signInWithPopup
export default app;
AuthContext.js
import React, { useContext, useState, useEffect } from "react"
import { auth, provider, signInWithGooglePopUp } from "../firebase"
const AuthContext = React.createContext()
export function useAuth() {
return useContext(AuthContext)
}
export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState()
const [loading, setLoading] = useState(true)
function signup(email, password) {
return auth.createUserWithEmailAndPassword(email, password)
}
function login(email, password) {
return auth.signInWithEmailAndPassword(email, password)
}
function logout() {
return auth.signOut()
}
function resetPassword(email) {
alert('')
return auth.sendPasswordResetEmail(email).then((a) => {
alert(a)
})
}
function updateEmail(email) {
return currentUser.updateEmail(email)
}
function updatePassword(password) {
return currentUser.updatePassword(password)
}
function signupWithGoogle() {
return signInWithGooglePopUp(auth, provider).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error)
})
}
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged(user => {
setCurrentUser(user)
setLoading(false)
})
return unsubscribe
}, [])
const value = {
currentUser,
login,
signup,
logout,
resetPassword,
updateEmail,
updatePassword,
signupWithGoogle
}
return (
<AuthContext.Provider value={value}>
{!loading && children}
</AuthContext.Provider>
)
}
ForgotPassword.js
import React, { useRef, useState } from "react"
import { Form, Button, Card, Alert } from "react-bootstrap"
import { useAuth } from "../contexts/AuthContext"
import { Link } from "react-router-dom"
export default function ForgotPassword() {
const emailRef = useRef()
const { resetPassword } = useAuth()
const [error, setError] = useState("")
const [message, setMessage] = useState("")
const [loading, setLoading] = useState(false)
async function handleSubmit(e) {
e.preventDefault()
try {
setMessage("")
setError("")
setLoading(true)
console.log('wait')
await resetPassword(emailRef.current.value)
console.log('done')
setMessage("Check your inbox for further instructions")
} catch (error) {
console.log(error)
setError("Failed to reset password")
}
setLoading(false)
}
return (
<>
<Card>
<Card.Body>
<h2 className="text-center mb-4">Password Reset</h2>
{error && <Alert variant="danger">{error}</Alert>}
{message && <Alert variant="success">{message}</Alert>}
<Form onSubmit={handleSubmit}>
<Form.Group id="email">
<Form.Label>Email</Form.Label>
<Form.Control type="email" ref={emailRef} required />
</Form.Group>
<Button disabled={loading} className="w-100" type="submit">
Reset Password
</Button>
</Form>
<div className="w-100 text-center mt-3">
<Link to="/login">Login</Link>
</div>
</Card.Body>
</Card>
<div className="w-100 text-center mt-2">
Need an account? <Link to="/signup">Sign Up</Link>
</div>
</>
)
}
What's wrong here, Thanks in Advance.
You are using Firebase Modular SDK (V9.0.0+) where sendPasswordResetEmail is a function and not a method on Auth instance. So that should be:
import { sendPasswordResetEmail } from "firebase/auth"
import { auth } from "../firebase"
function resetPassword(email) {
return sendPasswordResetEmail(auth, email).then((a) => {
alert("Password reset email sent")
})
}
The same applies for others functions like createUserWithEmailAndPassword(), signOut(), etc. I'm not sure why the error shows up for this one only.
Do checkout the documentation of Firebase Auth to learn more about these functions.

Categories