It's just a script that sends email to firestore db, I don't know how to check for repeated emials in db. Code:
const Newsletter = () => {
const [input, setInput] = useState("");
const inputHandler = (e) => {
setInput(e.target.value)
}
const submitHandler = (e) => {
e.preventDefault();
if(input) {
console.log(input);
addDoc(collection(db, 'emails'),{
email: input,
time: Timestamp.now(),
})
}
}
I understand that you want to avoid that two Firestore documents of the emails collection contain the same value for their email field. One possible approach is to use a Transaction.
Since you are using React and the JS SDK you cannot use a Query in your Transaction. So you need to maintain another collection in which you store one document for each existing email address, with the email address as the ID of the document.
This way you can use a code like the following (untested):
import { runTransaction, ... } from "firebase/firestore";
try {
const emailToBeSaved = ....; // The new email
await runTransaction(db, async (transaction) => {
const emailDocRef = doc(db, 'existingEmails', emailToBeSaved);
const emailDoc = await transaction.get(emailDocRef);
if (emailDoc.exists()) {
throw 'This email is already present in the DB';
}
transaction
.set(doc(db, 'existingEmails', emailToBeSaved),
{
email: emailToBeSaved
}) // The value of this last parameter is not important, it could be {foo: "bar"}
.set(doc(collection(db, 'emails')),
{
email: emailToBeSaved,
time: Timestamp.now(),
})
});
console.log("Transaction successfully committed!");
} catch (e) {
console.log("Transaction failed: ", e);
}
So, we check, in the Transaction if a doc with ID = emailToBeSaved exists in the existingEmails collection.
existingEmails collection (with dummy data, we are just interested by the ID of the document, not its content) and we add the doc in the emails collection. These two writes being done in the Transaction.Note that you could simplify the approach by using the email values as the ID of the documents in the emails collection. This way, no need to have an extra existingEmails collection.