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

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() };
})
);
});
};

Related

How to get the data of a query from firebase database in react-native

I am trying to list the data of each document that i am fetching from a firebase query, However I am being able to show the data through flatlist, Iwoudl love to iterate the data in another way in order to add it to a PDF that will be created from the app.
const [Annotations, setAnnotations] = useState(null);
useEffect(() => {
const q = query(
collection(db, "notifications"),
orderBy("createdAt", "desc")
);
console.log("Query:");
console.log(q);
onSnapshot(q, (test) => {
setAnnotations(test.docs);
});
}, []);
From the code above I am getting some unneccesary data, however I’d like to get the data of the document, hope you help me, thanks!
What you're seeing are the internals of the Firestore DocumentSnapshot and QueryDocumentSnapshot classes, which is indeed pretty meaningless.
If you only want to use the data:
onSnapshot(q, (test) => {
setAnnotations(test.docs.map((doc) => doc.data()));
});
If you want the data and document ID:
onSnapshot(q, (test) => {
setAnnotations(test.docs.map((doc) => { doc.id, ...doc.data() }));
});

How do I retrieve the UID's that I have placed as documents in my Firebase Cloud Firestore

I am currently using expo react-native to create a feed in which all user posts could be retrieved, I have come up with a solution to input all of the current users posts
const Posts = firebase.firestore().collection("posts").doc(user.uid).collection("userPosts");
const [users, setUsers] = useState([]);
useEffect(async () =>{
Posts
.onSnapshot(
querySnapshot => {
const users = []
querySnapshot.forEach((doc) => {
const { caption, creation, DownloadURL} = doc.data()
users.push({
id: doc.id,
caption,
creation,
DownloadURL,
})
})
setUsers(users)
}
)
}, [])
but I could not find a way to get retrieve all the UID's of all the users with posts in order for me to access all the posts, my database goes as follows:
posts(base collection with UID's of users)->userPosts( with UIDS of each post and fields for posts )
For reference I have also tried using the same format but to no avail as I tried to pass the values and it led to 'undefined', closest I have gone is get this on the console log:
The code for the above is here:
const AllUids = firebase.firestore().collection("posts");
const [uids, setUids] = useState([]);
useEffect(async () =>{
AllUids
.onSnapshot(
querySnapshot => {
const uids = []
querySnapshot.forEach((doc) => {
const {id} = doc.data()
uids.push({
id: doc.id,
id
})
})
setUids(uids)
}
)
}, [])
console.log(uids)
Both loading data from Firestore and setting modifying the state in a React app are asynchronous operations, so by the time your console.log(uids) runs neither of those will have completed yet.
The easiest way to log the uid value, is to use another effect that depends on that state variable:
useEffect(() => {
console.log(uids);
}, [uids]);
This has been coming up repeatedly in the past days, but I'm not sure why folks are suddenly bumping into this more than before.

getDocs - firebase react native

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,
})
})

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 }
}

Firestore query with where returning undefined snapshot (Vue.js / Firestore / Vuefire)

I'm currently using Firestore/Vue.js with Vuefire support.
The Firestore DB has just one collection with a couple of users inside:
Users
001
name: Jack
uid: {Firebase auth ID}
org_id: 123
002
name: Frank
uid {Firebase auth ID}
org_id: 456
in the Vue component, I try to query the DB to get the first user using the auth ID (which is currently stored in a Vuex Store)
<script>
import { db } from "../main.js";
export default {
data() {
return {
items: [] // to be used later
};
},
created() {
this.getServices();
},
methods: {
getServices() {
console.log(this.$store.state.user.uid);
db.collection("users")
//.doc("001")
.where("uid", "==", this.$store.state.user.uid)
.get()
.then((snapshot) => {
console.log(snapshot);
if (snapshot != null && snapshot.data != null) {
const user = snapshot.data();
// do something with document
let org_id = user["org_id"];
console.log("org id:" + org_id);
} else {
console.log("No data returned!");
}
});
},
},
};
</script>
the code always returns an empty snapshot. Checks I have performed:
accessing the document directly using its doc ID works
this.$store.state.user.uid is correctly set
hard-coding the uid in the where clause gives the same error
I'm a total beginner but it looks to me the where clause is not working.
Since, with db.collection("users").where("uid", "==", this.$store.state.user.uid) you define a Query, the snapshot Object is actually a QuerySnapshot and not a DocumentSnapshot.
So snapshot.data != null is always false because a QuerySnapshot does not have such a property. It is also the case for snapshot.data() != null => it is always false because a QuerySnapshot does not have such a method.
You should either loop over the QuerySnapshot with the forEach() method or use map on the docs property, as shown in the Vuefire example (see "retrieve a collection"):
db.collection("users")
.where("uid", "==", this.$store.state.user.uid)
.get()
.then((snapshot) => {
const documents = snapshot.docs.map(doc => doc.data())
// do something with documents
})

Categories

Resources