I need to save the username in my Firestore Database while creating the user. I'm using Firebase (v9) with React. The code is Below.
A user is created but in the Firestore Database user is not added.
What is the way to use setDoc
inside createUserWithEmailAndPassword
Can someone help me with the code?
import Box from "@mui/material/Box";
import OutlinedInput from "@mui/material/OutlinedInput";
import Button from "@mui/material/Button";
import Alert from "@mui/material/Alert";
import { Link, Outlet } from "react-router-dom";
import {
collection,
query,
onSnapshot,
setDoc,
serverTimestamp,
doc,
} from "firebase/firestore";
import { createUserWithEmailAndPassword } from "firebase/auth";
import { db, auth } from "../../../firebase";
import IGLogo from "../../../images/instagram-logo.png";
import "./SignUpForm.scss";
function SignUpForm() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [username, setUsername] = useState("");
const [successalert, setSuccessAlert] = useState(undefined);
const [failalert, setFailAlert] = useState(undefined);
//const [user, setUser] = useState(undefined);
useEffect(() => {
const timeId = setTimeout(() => {
// After 3 seconds set the show value to false
setSuccessAlert(undefined);
}, 3000);
return () => {
clearTimeout(timeId);
};
});
useEffect(() => {
const timeId = setTimeout(() => {
// After 3 seconds set the show value to false
setFailAlert(undefined);
}, 3000);
return () => {
clearTimeout(timeId);
};
});
useEffect(() => {
const timeId = setTimeout(() => {
// After 3 seconds set the show value to false
setFailAlert(undefined);
}, 3000);
return () => {
clearTimeout(timeId);
};
});
const instagramSignUp = (event) => {
event.preventDefault();
const q = query(collection(db, "users"));
onSnapshot(q, (querySnapshot) => {
querySnapshot.docs.forEach((doc) => {
if (doc.id === username) {
setFailAlert({ type: "userexist" });
} else {
createUserWithEmailAndPassword(auth, email, password)
.then((userCreated) => {
setDoc(doc(db, "users", username), {
timestamp: serverTimestamp(),
})
.then(() => {
setSuccessAlert({ type: "success" });
console.log("user created in collection");
})
.catch((error) => {
console.log(error.message);
});
})
.catch((error) => {
console.log(
"createUserWithEmailAndPassword = "
error.message
);
});
}
});
});
};
return (
<>
<div className="component__signupalerts">
{successalert?.type === "success" && (
<Alert variant="filled" severity="success">
Account Created Successfully. Please check your Email
for Verification.
</Alert>
)}
{failalert?.type === "userexist" && (
<Alert variant="filled" severity="error">
Username already taken
</Alert>
)}
</div>
<div className="component__signupform">
<img src={IGLogo} alt="" />
<Box component="form" className="component__signupform--box">
<OutlinedInput
className="component__loginform--input"
type="text"
placeholder="Username"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
<OutlinedInput
className="component__signupform--input"
type="email"
placeholder="Email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<OutlinedInput
className="component__signupform--input"
type="password"
placeholder="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<Button
className="component__signupform--button"
type="submit"
variant="contained"
onClick={instagramSignUp}
>
Sign Up
</Button>
<Link to="/" className="component__signupform--button">
Sign In
</Link>
</Box>
</div>
<Outlet />
</>
);
}
export default SignUpForm;
Console.log "doc is not a function"
CodePudding user response:
The problem is that you have two definitions of doc
in your code:
- First you
import { ...., doc, ... } from "firebase/firestore";
. - Then you also define it in
querySnapshot.docs.forEach((doc) => {
.
The doc
in that second line hides the one that you imported.
The easiest fix is to name the variable of forEach
something else:
onSnapshot(q, (querySnapshot) => {
querySnapshot.docs.forEach((docSnapshot) => {
if (docSnapshot.id === username) {
...