My firebase Create User trigger 2 times instead of one - reactjs

Creating a react app usign react-firebase-hook,firebase,react-hook-form,daisyUI
The problem is When I am pressing submit button it triggers 2 times in the console and when using the Button; Sign Up With Google it triggers 3times.Thanks for your time in advance.
In SingUP function:
import auth from '../../firebase.init';
import { useSignInWithGoogle } from 'react-firebase-hooks/auth';
import { useForm } from "react-hook-form";
import { useCreateUserWithEmailAndPassword } from 'react-firebase-hooks/auth';
function SignUp() {
const [signInWihGoogle, googleUser, googleLoading, googleError] = useSignInWithGoogle(auth);
const { register, formState: { errors }, handleSubmit } = useForm();
const [
createUserWithEmailAndPassword,
user,
loading,
error,
] = useCreateUserWithEmailAndPassword(auth);
This function is triggering:
const onSubmit = data =>{
createUserWithEmailAndPassword(data.email,data.password);
alert('You successfully created your account');
}
<form onSubmit={handleSubmit(onSubmit)}>
<div class="form-control w-full max-w-xs">
<label class="label">
<span class="label-text">Name</span>
</label>
<input
type="text"
placeholder="Pls type name here"
class="input input-bordered w-full max-w-xs"
{...register("name", {
required:{
value: true,
message:'Name is Required'
},
minLength: {
value:2,
message:'Name must be 2 or more characters
}
})}/>
</div>
... .... ...
<input
type='submit'
value= 'Signup'
class="btn w-full max-w-xs text-white"/>
</form>
<p className='text-center text-xs pt-1'>Already have an account?<Link
className='text-secondary' to='/login'> Please Login</Link></p>
<div class="divider">OR</div>
<button
onClick={() => signInWihGoogle()}
class="btn btn-outline">Continue with Google</button>
</div>

Do you still have the strict mode tag in your App?
If so: delete it and if you want you can read more on it here: https://reactjs.org/docs/strict-mode.html

Related

Navigate with React does not show me the component I want to go to, it does not find the path

This would be my code, I am making a small application with an internal database and a registration form. I would like that, when the user registers with a different username than the ones I have created in my database and clicks on register, he/she will be redirected to my Planets component.
This my the error url: http://localhost:3000/Registration/Planets
This should be: http://localhost:3000/Planets
This is my code in the Registration component:
import { Link } from 'react-router-dom';
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import swal from 'sweetalert';
import yoda from '../images/yoda.png';
function Registration() {
//error
const [errorMessages, setErrorMessages] = useState({});
const [isSubmitted, setIsSubmitted] = useState(false);
const navigate = useNavigate();
//error
const renderErrorMessage = (name) =>
name === errorMessages.name && (
<div className="error">{errorMessages.message}</div>
);
// User Login info
const database = [
{
username: 'Luke',
},
{
username: 'Leia',
},
];
const errors = {
uname: 'This user already exists',
};
const alert = () => {
swal({
title: 'Confirming registration',
icon: 'success',
button: 'Ok',
timer: '2000',
});
};
function handleSubmit(event) {
//Prevent page reload
event.preventDefault();
var { uname } = document.forms[0];
// Find user login info
const userData = database.find((user) => user.username === uname.value);
// Compare user info
if (userData) {
if (userData.username === uname.value) {
// Invalid password
setErrorMessages({ name: 'uname', message: errors.uname });
}
} else {
// Username not found
setIsSubmitted(true);
navigate('Planets');
alert();
}
}
return (
<>
<div className="main">
<section className="main__section">
<form className="main__section__form" onSubmit={handleSubmit}>
<h3 className="main__section__form__title">CREATE YOUR ACCOUNT</h3>
<div className="input-container">
<input type="text" name="uname" placeholder="Username" required />
{renderErrorMessage('uname')}
</div>
<div className="input-container">
<input
type="password"
name="pass"
placeholder="Password"
required
/>
</div>
<div className="input-container">
<input
type="text"
name="pass"
placeholder="First Name"
required
/>
</div>
<div className="input-container">
<input type="text" name="pass" placeholder="Last Name" required />
</div>
<div className="button-container">
<button className="button">Register</button>
</div>
<Link to="/">
<p className="main__section__form__p">
Already have an account?{' '}
<span className="main__section__form__span">Back to Login</span>
</p>
</Link>
</form>
</section>
<div>
<img className="main__imageYoda" src={yoda} alt="Yoda" />
</div>
</div>
</>
);
}
You actually need to replace the previous path and not push a new one into the history.
Try to use navigate("/Planets", { replace: true }).
Also keep in mind that routes should start with a lower case letter (/registration, /planets)

Why is my error message not showing up when I click enter?

I'm trying to have an error message pop up if the user submits an email without inputting a recipient, however, nothing happens upon clicking enter. Is there something I'm missing? pls help
import React from "react";
import "./SendMail.css";
import CloseIcon from "#mui/icons-material/Close";
import { Button } from "#mui/material";
import { useForm } from "react-hook-form";
const SendMail = () => {
const {
register,
handleSubmit,
watch,
formState: { errors },
} = useForm();
const onSubmit = (formData) => {
console.log(formData);
};
return (
<div className="sendmail">
<div className="sendmail__header">
<h3>New Message</h3>
<CloseIcon className="sendmail__close" />
</div>
<form onSubmit={handleSubmit(onSubmit)}>
<input
name="to"
type="text"
placeholder="To"
{...register("to", { required: true })}
/>
{errors.to && <p className="sendMail__error">To is Required</p>}
<div className="sendmail__options">
<Button>Send</Button>
</div>
</form>
</div>
);
};
export default SendMail;
Add the submit type in your button
<div className="sendmail__options">
<Button type="submit">Send</Button>
</div>

React Firebase is not getting data from React Hook form

This is what I'm stuck with for last couple of hours. I have tried default values from react hook form. I kinda getting the user input on the console but for firebase it's showing error. It is working with the normal input system
import React, { useEffect } from "react";
import {
useAuthState,
useCreateUserWithEmailAndPassword,
} from "react-firebase-hooks/auth";
import { useForm } from "react-hook-form";
import { Link, useNavigate } from "react-router-dom";
import { toast } from "react-toastify";
import auth from "../../firebase.init";
import Loading from "../Shared/Loading";
import GoogleLogin from "./GoogleLogin";
const Signup = () => {
const [createUserWithEmailAndPassword,loading] =
useCreateUserWithEmailAndPassword(auth);
const navigate = useNavigate();
const [user] = useAuthState(auth);
useEffect(() => {
if (user) {
navigate("/home");
}
}, [navigate, user]);
const {
register,
formState: { errors },
handleSubmit,
} = useForm();
const onSubmit = (data) => {
createUserWithEmailAndPassword(data);
if (user) {
toast.success("Successfully Registered");
}
console.log(data);
};
if(loading){
return <Loading></Loading>
}
return (
<section className="container mx-auto px-5 gap-5 md:px-12">
<form className="py-5 card" onSubmit={handleSubmit(onSubmit)}>
<div className="mt-5 mb-5">
<input
type="text"
className="input input-bordered py-5"
placeholder="Your Full Name"
{...register("name", {
required: { value: true, message: "Name is required" },
maxLength: 80,
pattern: {
value: /^[\w'\-,.][^0-9_!¡?÷?¿/\\+=##$%ˆ&*(){}|~<>;:[\]]{2,}$/,
message: `Don't use special characters`,
},
})}
/>
<br />
</div>
<div className="form-control w-full max-w-xs">
<label className="label">
<span className="label-text">Email</span>
</label>
<input
type="email"
placeholder="Your Email"
className="input input-bordered w-full max-w-xs"
{...register("email", {
required: {
value: true,
message: "Email is Required",
},
pattern: {
value: /[a-z0-9]+#[a-z]+\.[a-z]{2,3}/,
message: "Provide a valid Email",
},
})}
/>
<label className="label">
{errors.email?.type === "required" && (
<span className="label-text-alt text-red-500">
{errors.email.message}
</span>
)}
{errors.email?.type === "pattern" && (
<span className="label-text-alt text-red-500">
{errors.email.message}
</span>
)}
</label>
</div>
<div>
<input
type="password"
placeholder="Password"
className="input input-bordered"
{...register("password", {
required: {
value: true,
message: `Please provide a password between 6 to 30 character`,
},
})}
/>
<label className="label">
{errors.password?.type === "required" && (
<span className="label-text-alt text-red-500">
{errors.password.message}
</span>
)}
{errors.password?.type === "pattern" && (
<span className="label-text-alt text-red-500">
{errors.password.message}
</span>
)}
</label>
</div>
<input className="btn btn-primary" value="Register" type="submit" />
</form>
<GoogleLogin></GoogleLogin>
<div>
<Link className="btn btn-se" to="/login">
Login
</Link>
</div>
</section>
);
};
export default Signup;
So after submitting, I can see the data on console but can't send them to firebase.

firebase `onAuthStateChanged` function returns null each time

When I'm calling handleAuth function after registeration, a user has been created(I can see him being added to the firebase authentication web), but onAuthStateChanged logs null.
I'm caling it inside useEffect after a user is successfully signed in. console.log(data) inside it returns the user's token from the server response data.
Why's onAuthStateChanged returns null?
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap-icons/font/bootstrap-icons.css';
import { useEffect, useRef, useState } from 'react';
import useFetch from '../hooks/useFetch';
import { useLocation } from 'react-router';
import { auth } from '../config/firebaseConfig';
export default function Authenticate() : JSX.Element {
const url = useLocation().pathname;
const { fetchData, data, error, loading } = useFetch();
const email = useRef() as React.MutableRefObject<HTMLInputElement>;
const password = useRef() as React.MutableRefObject<HTMLInputElement>;
const [show, setShow] = useState(false);
const handleAuth = (e : React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const path = (e.nativeEvent as any).submitter.name === 'login' ?
`${url}/login/email` : `${url}/register`;
fetchData(path, 'POST', {
email : email.current.value,
password : password.current.value
});
}
useEffect(() => {
if(data)
{
console.log(data)
auth.onAuthStateChanged(user => console.log(user));
}
}, [data])
return (
<div className="d-flex justify-content-center align-items-center vh-100 bg-white">
<div className="p-5 border border-2 border-success">
<h1 className="fw-light fs-2 text-center">Authenticate</h1>
<br/>
<form onSubmit={e => handleAuth(e)}>
<div className="form-group">
<label>Email</label>
<div className="input-group">
<span className="input-group-text bi bi-person-circle"></span>
<input type="email" ref={email} className="form-control" placeholder="boomer#bommer.com" required/>
</div>
</div>
<div className="form-group">
<label>Password</label>
<div className="input-group">
<span className="input-group-text bi bi-key-fill"/>
<input type={show ? "text" : "password"} className="form-control" ref={password} placeholder="enter your password" required/>
<button type="button" className={`input-group-text text-decoration-none bi bi-${show ? 'eye-fill' : 'eye-slash-fill' }`} onClick={() => setShow(!show)}/>
</div>
</div>
<br/>
{ error && <p className={`alert alert-danger p-1 text-center`} role="alert">{error}</p> }
<div className="d-flex justify-content-between">
<button type="submit" name="register" className="btn btn-primary" disabled={loading}>Register</button>
<button type="submit" name="login" className="btn btn-primary" disabled={loading}>Login</button>
</div>
</form>
</div>
</div>
);
}
The creation of the user is different from the authentication of the use.
While creating the user, you will storing new user credentials (email / password), while when authenticating the user you will matching the provided credentials against the stored ones.
The listener onAuthStateChanged seems to be well installed but you are not engaging any authentication so that it submits a new values: the authenticated user.
Once the user has been successfully created, and given his account has been validated, you can trigger a sign in request as follows:
const handleAuth = (e : React.FormEvent<HTMLFormElement>) => {
// ...
fetchData(path, 'POST', {
email : email.current.value,
password : password.current.value
}).then(() => auth.signInWithEmailAndPassword(email.current.value, password.current.value))
}
Then the registered onAuthStateChanged listener will get triggered with the proper user identity.

Modal box doesn't open in react-redux app

I am working on a React-Redux app, currently working on showing a modal box on a button click of a form. But I can't make it work. I have tried so many things but can't figure out why the modal box doesn't appear. Here is my code.
The Modal component file
import React from 'react'
import { connectModal } from 'redux-modal'
import { Button, Modal } from 'react-bootstrap'
import UpdatePasswordForm from 'forms/updatepassword'
export class UpdatePassword extends React.Component {
constructor(props) {
super(props)
}
renderCloseIcon (handleHide) {
return (
<button className='close' onClick={ handleHide }>
<span>
<i className="modal__close"/>
</span>
</button>
)
}
renderModalLogo () {
return (
<div className="modal__header modal__header_login">
<div className="modal__logo"></div>
</div>
)
}
render() {
const { show, handleHide } = this.props
return (
<Modal
show={ show }
onHide={ handleHide }
backdrop={ true }
className="modal_dark modal_center"
dialogClassName="modal-background-fix">
<div className="modal__container">
{ this.renderCloseIcon(handleHide) }
{ this.renderModalLogo() }
<div className="modal__content">
<UpdatePasswordForm onSubmit={() => {}}/>
</div>
</div>
</Modal>
)
}
}
export default connectModal({name: 'updatepassword'})(UpdatePassword)
The form that is loaded in the Modal
import React from 'react'
import { Field, reduxForm } from 'redux-form'
import Text from '../containers/Text'
const I18n = {}
I18n.t = Text.t
const UpdatePasswordForm = (props) => {
const { handleSubmit, pristine, reset, submitting } = props
return (
<form onSubmit={handleSubmit}>
<fieldset className="form-group">
<Field name="current_password" component="input"
type="password" placeholder="Password" className="form-control" />
</fieldset>
<fieldset className="form-group">
<Field name="password" component="input"
type="password" placeholder="New Password" className="form-control" />
</fieldset>
<fieldset className="form-group">
<Field name="password_confirm" component="input" type="password"
placeholder="New password confirmation" className="form-control" />
</fieldset>
<fieldset className="form-group form-group_btns">
<button type="submit" disabled={pristine || submitting} className="btn btn-primary btn-block">
{ 'CHANGE PASSWORD' }
</button>
</fieldset>
</form>
)
}
export default reduxForm({
form: 'updatepassword' // a unique identifier for this form
})(UpdatePasswordForm)
The file where modal is called
import React from 'react';
import './EditInformation.scss'
import { show } from 'redux-modal'
import UpdatePassword from './Modals/UpdatePassword'
// TODO fix stylee stylee
// TODO onChange is not updating correctly, FIX!
const EditInformation = ({ onSubmit, onChange, user, formSubmitting }) => {
return (
<div>
<UpdatePassword />
<form className='form-line form-line_light'>
<div className='col-xs-16 col-sm-8'>
<fieldset className='form-group'>
<button
onClick={(e) => {
show('updatepassword')
e.preventDefault()
}}
className='btn btn-secondary btn-lg profile-edit__addcard'
style={ { position: 'relative', top: '-27px' } }>
<i className='fa fa-plus'/>Vaihda salasana
</button>
</fieldset>
</div>
</form>
</div>
);
};
export default EditInformation;
In the beginning of our project, I tried to develope my own modal with all custom functionalities. Many problems has occured. I searched some open source projects, then I found a project on github. You should use react-modal, It's easy to use and well designed.
react-modal
There was a stupid mistake that I have figured out now. But I should get an error for that which I am not getting. I had to pass 'show' to the const EditInformation which I have done now and it is working all fine. Here is that part of the code:
const EditInformation = ({ onSubmit, onChange, user, formSubmitting, show }) => {
I wasn't passing 'show' previously.

Resources