getDocs - firebase react native - javascript

I want to get a document and to update.
I tried used this code, but he dont accept the "idDoc":
const Doc = query(collection(database, "user_veic"),where("email", "==", auth.currentUser?.email),where("kmF", "==", ""));
getDocs(Doc).then((querySnapshot) => {
querySnapshot.forEach((doc) => {
console.log(`${doc.id} => ${doc.data()}`);
const idDoc = doc.id
})
})
.then(
updateDoc(doc(database, "user_veic", idDoc), {
kmF: "teste1",
km: "teste1",
}))
^^^^: FirebaseError: Invalid document reference. Document references must have an even number of segments, but user_veic has 1
I tried this:
const Doc = query(collection(database, "user_veic"),where("email", "==", auth.currentUser?.email),where("kmF", "==", ""));
getDocs(Doc).then((querySnapshot) => {
querySnapshot.forEach((doc) => {
console.log(`${doc.id} => ${doc.data()}`);
const idDoc = doc(database, "user_veic", doc.id)
updateDoc(idDoc, {
kmF: "teste1",
km: "teste1",
})
})
})
^^^^: [Unhandled promise rejection: TypeError: doc is not a function. (In 'doc(database, "user_veic", doc.id)', 'doc' is an instance of lh)]
What did i do wrong?

In your first code example, you declare const idDoc inside of the callback parameter to .forEach(). That variable does not exist outside of the callback function. You then try to use it in the updateDoc() in a completely different block of code. It is undefined at that point, thus you are getting an error that you aren't passing enough parameters.
In your second code example, which is much closer to what you want to do, based on the error message it looks like you aren't importing doc with the rest of the Firestore functions from firebase/firestore.

RESOLVIDO #Greg thank you
const Doc = query(collection(database, "user_veic"),where("email", "==", auth.currentUser?.email),where("kmF", "==", ""));
getDocs(Doc).then((querySnapshot) => {
let values = null;
querySnapshot.forEach((doc) => {
console.log(`${doc.id} => ${doc.data()}`);
values = doc.id;
});
var transactionUpdate = database.collection("user_veic").doc(values);
transactionUpdate.update({
kmF: kmF,
})
})

Related

Firebase Error "Uncaught Error in snapshot listener: FirebaseError: The query requires an index"

I'm getting the above error when I run the following query. I can visit the link provided to create an index, but if I understand this correctly I don't think that is feasible since the query is searching through the "members" map for the current users ID which will obviously change depending on the user. Is there some kind of workaround to this issue or would I need to restructure my database?
const subscribeChats = () => {
const chatsQuery = query(
collection(db, "chats"),
where(`members.${getAuth().currentUser.uid}.inChat`, "==", true),
where(`members.${getAuth().currentUser.uid}.isHidingChat`, "==", false),
orderBy("lastActive", "desc")
);
return onSnapshot(chatsQuery, (snapshot) => {
setChatsList(
snapshot.docs.map((doc) => {
return { id: doc.id, data: doc.data() };
})
);
});
};

How to query a single document by custom parameter and update it in Firebase 9

I have a custom ID in my Firebase documents. I want to get a single document querying by that custom ID and modify it. I'm using firebase v9.
Here's my code so far:
const toggleLike = async () => {
const q = query(collection(db, 'mixrCocktails'), where('id', '==', cocktailId))
const querySnapshot = await getDocs(q)
const result: any[] = []
querySnapshot.forEach(doc => result.push(doc.data()) )
if (!isLiked) {
await updateDoc(result[0], { userLikes: arrayUnion(publisherId) })
setIsLiked(true)
}
else {
await updateDoc(result[0], { userLikes: arrayRemove(publisherId) })
setIsLiked(false)
}
}
The query works fine, but the problem is when I run updateDoc . I get the following error:
Uncaught (in promise) FirebaseError: Expected type 'Zu', but it was: a custom Object object
I tried running result[0].update({ userLikes: arrayUnion(publisherId) }) and I get Uncaught (in promise) TypeError: result[0].update is not a function.
I've also tried
const docRef = doc(db, "mixrCocktails", cocktail.id)
await updateDoc(docRef, { userLikes: arrayUnion(publisherId) })
And I get
Uncaught (in promise) TypeError: n.indexOf is not a function
In the docs (https://firebase.google.com/docs/firestore/manage-data/add-data) I see they use a document ref in the following way:
import { doc, updateDoc, arrayUnion, arrayRemove } from "firebase/firestore";
const washingtonRef = doc(db, "cities", "DC");
// Atomically add a new region to the "regions" array field.
await updateDoc(washingtonRef, {
regions: arrayUnion("greater_virginia")
});
In the example, I understand "DC" is the ID Firebase sets for the document. But how can I create a ref by querying for another field different than that?
Full code can be found here: https://github.com/coccagerman/mixr
Thanks in advance!
Based on your question, if I understand it correctly. You want to query a document using where before updating the document result.
You're not referencing the updateDoc() properly. Check the snippet that I wrote based on your snippet above. Here's some options:
Using .map:
const q = query(collection(db, 'mixrCocktails'), where('id', '==', cocktailId));
const querySnapshot = await getDocs(q);
const documents = querySnapshot.docs.map((doc) => ({ id: doc.id, ...doc.data() }));
for (const document of documents) {
// console.log(document.id);
const documentRef = doc(db, 'mixCocktails', document.id);
if (!isLiked) {
await updateDoc(documentRef, { userLikes: arrayUnion(publisherId) })
setIsLiked(true)
}
else {
await updateDoc(documentRef, { userLikes: arrayRemove(publisherId) })
setIsLiked(false)
}
}
Using async method:
async function updateDocuments (document) {
// console.log(document.id);
const documentRef = doc(db, 'mixrCocktails', document.id);
if (!isLiked) {
await updateDoc(documentRef, { userLikes: arrayUnion(publisherId) })
setIsLiked(true)
}
else {
await updateDoc(documentRef, { userLikes: arrayRemove(publisherId) })
setIsLiked(false)
}
}
const q = query(collection(db, 'mixrCocktails'), where('id', '==', cocktailId));
const querySnapshot = await getDocs(q);
querySnapshot.forEach((document) => {
updateDocuments(document);
});
You may still improve the written code above for your use-case.

Firebase onSnapshot in react error, "Expected type 'bc', but it was: a custom he object"

I was following this tutorial https://www.sitepoint.com/reddit-clone-react-firebase/.
Earlier it was really simple just call onSnapshot after the document is fetched, but here it is a separate function, and now here comes the issue, when I try to call that onSnapshot by passing document, but it always says,no matter what type of data I tried to pass it as the first param, it always says, it is not type of 'bc' which it expects.
FirebaseError: Expected type 'bc', but it was: a custom he object
useEffect(async () => {
const postsCollection = collection(db, "posts");
const orderedCollection = query(
postsCollection,
orderBy("createdAt", "desc")
);
try {
onSnapshot(
orderedCollection, // here I think the problem is!
(querySnapshot) => {
console.log("yahaan se problem hai");
console.log(querySnapshot);
const _posts = [];
querySnapshot.forEach((doc) => {
console.log(doc);
_posts.push({
id: doc.id,
...doc.data(),
});
});
console.log(_posts);
// setPosts(_posts);
},
(error) => {
console.log("error occured: ", error);
},
() => {
console.log("completed");
}
);
} catch (e) {
console.log("ye kya drama hai:", e);
} finally {
console.log("finally");
}
}, []);
Okey, so I had the same problem and I found a solution after struggling with the newest version of firebase for a while.
I don't know if you're using a class component or a functional one, in this example i'm using a funcional component but I assume it'll work the same if you replace the react hooks.
import { getFirestore, collection } from 'firebase/firestore'
const db = getFirestore();
const colRef = collection(db, "team")
const [results, setResults] = useState([]);
useEffect(() => {
let isMounted = true;
onSnapshot(colRef, (snapshot) => {
if (isMounted) {
const results= snapshot.docs.map((doc) => {return {...doc.data(), id: doc.id}});
setResults(results)
}
});
return () => { isMounted = false };
}, []);
This way your component'll listen to updates everytime the data changes, after that you can personalize it using querys but i wanted to show you a simple example so it's easy to understand.
I had the same problem, unfortunately, the above didn't help me. in my case I was actually importing form functions and types from '#firebase/firestore' and others from 'firebase/firestore'... this was done by autoImport. the moment I made all of them get the types and functions from the same place it worked instantly
These kind of errors occur usually when the functions aren't used the way they're supposed to. I can't really tell where the problem comes from in your code but you may try the getDocs method instead and a state variable to store your values
try this code.
const [Results, setResults] = useState([]);
useEffect(() => {
const FetchedPosts = async () => {
const querySnapshot = await getDocs(
collection(db, 'posts'),
orderBy("createdAt", "desc")
);
querySnapshot.forEach((doc) => {
setResults((prevState) => [...prevState, doc.data()]);
});
};
FetchedPosts();
}, []);

Reading a value from Realtime Firebase

I have the following json structure:
Within "all" node I have an attribute "drinkId" and I'm trying to move it outside that child node bringing it one level up.
I'm trying to read the value without any luck
const cocktailRef= firebase
.database()
.ref("Ratings");
cocktailRef.once("value", (snapshot) => {
snapshot.forEach((child) => {
const drinkIdPass = child.ref.child("all").child("drinkId").value();
child.ref.update({ drinkId: drinkIdPass });
})
})
I've tried different variants of ".value()", same problem
There isn't any value() method on a DataSnapshot. It's val() Try refactoring your code like this:
const cocktailRef= firebase.database().ref("Ratings");
cocktailRef.once("value").then(async (snapshot) => {
const updates = { }
snapshot.forEach((child) => {
const drinkIdPass = child.val().all.drinkId
updates[`${child.key}/drinkId`] = drinkIdPass
})
await cocktailRef.update(updates)
console.log("Data updated")
})

How to get a single doc with React/Firestore?

All I want to do is to get a row (so called 'doc') from a data base.
so far, I have tried:
all with the 'aref'
const aref = firebase
.firestore()
.collection("polja")
.where("id", "==", match.params.id);
console.log(aref);
function getIt() {
const item = [];
setLoading(true);
aref.get().then((doc) => {
const data = doc.data();
setItem(item);
console.log(item);
setLoading(false);
});
}
useEffect(() => {
getIt();
}, []);
this gave the following error:
To get a single document, you must specify the document ID:
firebase.firestore().collection("polja").doc(documentId).get().then((snapshot) => {
console.log(snapshot.data())
}).catch((e) => console.log(e))
Also you should not use .where() to get just a single document, but there is an issue I found in your original code.
If you look carefully, the parameter in .where() is a string "match.params.id". That seems to be a dynamic value being fetched from somewhere else. Please remove the quotes and try again.
firebase.firestore().collection("polja").where("id", "==", match.params.id).get()
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
// doc.data() is never undefined for query doc snapshots
console.log(doc.id, " => ", doc.data());
});
})
.catch((error) => {
console.log("Error getting documents: ", error);
});
Try adding a catch block as shown which might help catch any errors. Make sure your security rules also allow you to fetch the data.
Also if any error is logged in the console, share a screenshot of it.
To get single document form firebase firestore you should first know if you are using the modular firebase 9.+ version or firebase version < 9.
In new modular firebase firestore(version 9.+) it should be like this:
import { getFirestore, collection, query, getDocs } from 'firebase/firestore'
async read(id) {
const firestore = getFirestore()
const docRef = doc(firestore, this.collectionPath, id)
const docSnap = await getDoc(docRef)
const data = docSnap.exists() ? docSnap.data() : null
if (data === null || data === undefined) return null
return { id, ...data }
}
If you are using not modular Firebase firestore( < version 9) then the same function should look something like this:
async read(id) {
const result = await (await firestore())
.collection(this.collectionPath)
.doc(id)
.get()
const data = result.exists ? result.data() : null
if (data === null || data === undefined) return null
return { id, ...data }
}

Categories

Resources