Here is my code:
function loginHandler() {
firestore.collection("users").forEach(user => {
if (user.username === queryUsername && user.password === queryPassword) {
navigate("/");
}
else {
setMode("INCORRECT")
}
})
}
I am trying to check if a doc in the users collection of my firestore db has the username property of the queryUsername and the password property of the queryPassword. When I run this function:
function loginHandler() {
if (firestore.collection("users").doc("doc that definetly doesnt exist")) {
console.log("exists")
}
else {
console.log("doesnt exist")
}
}
It logs exists for some reason
1. Starting with the second code snippet
firebase.collection("someCollection").doc("some docID which might exist or not")
The code above returns an object or snapshot according to firebase which gives you informations about the document you are looking up whether it exists or not. By code implication your code will always return the document exist since an object passed to an if statement is always true. From firebase official documentation this will be the way to solve this
firebase.collection("SomeCollection").doc("some document ID which exists or not").get()
.then((user)=>{
if(user.exists){
console.log("exists");
} else{
console.log("doesn't exists");
}
})
2. From the First code snippet
SOME NOTES From the looks of things you want to perform some kind of authentication, though storing users real password is highly risky and a bad practice, if you want to store password you can hash them, but for illustration purpose i will use your code sample.
The first code snippet gets all document from firebase database and do the checking on the client side, this is inefficient and will not be a good practice assuming your collection size goes to infinity, i will attempt to fix your code and then provide a better solution
Your Code Solution When you read a firebase collection what you get is a snapshots of documents, you have to call .data() on each snapshot to get the actual document stored on firebase. Your code solution will now be like this asuming usernames and passwords are stored raw
function loginHandler() {
firestore.collection("users").get().then(users => {
users.forEach((user)=>{
if (user.data().username === queryUsername && user.data().password === queryPassword) {
navigate("/");
}
else {
setMode("INCORRECT")
}
})
})
}
The Efficient
The most efficient way is to run this codes from database level, in that case you dont have to accumulate costs as your app grows for document reads.
firestore.collection("users").where("username","==",queryUsername)
.where("password","==",querypassword).limit(1).get()
.then((result)=>{
if(result.exists){
console.log("do something after users creds are ok")
}else{
console.log("do something if not ok")
}
})
Note from the answer you have to create a compound index of username and password field in your firestore console check it out here
Not the limit i used is intentional so i can return only one document that matches and call .exists on the snapshot else it will return array of snapshots even if only one document can be found.