Я пытаюсь использовать функциональность .where() в firestore, чтобы определить, находится ли определенная строка в массиве в базе данных. Я пытался манипулировать первым параметром функции, добавляя скобки и другие вещи для обозначения частей массива, но безрезультатно.
//in this section I am getting the "yourLikes" integer (unrelated to the problem)
var liks = [];
var tempLiks = []
db.collection("users").where("uid", "= = ", uid)
.get()
.then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
tempLiks = doc.data().yourLikes;
// I am using a setTimeout() function to allow firebase to
// process the previous query and give me the doc.data().yourLikes for tempLiks
setTimeout(function(){
//Right here, the "usersLiked" data is an array, with a bunch of different values.
// I am trying to see if one of those values is doc.data().uid from my previous query. (I think) this is the problem.
db.collection("memeInfo").where("usersLiked", "= = ", doc.data().uid)
.get()
.then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
for (var i = 0; i < tempLiks.length; i++) {
liks.push([tempLiks[i],doc.data().likes])
console.info(liks)
}
})
})
},500)
Если у кого-то есть решение для запроса, чтобы увидеть, находятся ли отдельные значения в массивах, без использования цикла for навсегда (у меня, возможно, будут тысячи значений в массиве usersLiked), это было бы очень признательно.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы должны использовать оператор array_contains для фильтрации на основе значений массива, см. https://firebase.google.com/docs/firestore/query-data/queries#array_membership.
Поэтому вы должны адаптировать свой код следующим образом:
//....
db.collection("memeInfo").where("usersLiked", "array-contains", doc.data().uid)
.get()
.then(function(querySnapshot) {...})
Дополнительное замечание: с использованием setTimeout() для управления асинхронным аспектом запросов к Firestore не является правильным подходом (нет гарантии, что запрос будет выполнен менее чем за 500 мс). Вы должны управлять асинхронностью через промисы, возвращаемые методом get(). В частности, поскольку вы запускаете несколько запросов параллельно (через свои циклы), вам нужно использовать Promise.all().
ОБНОВИТЬ после вашего комментария. Вы можете использовать Promise.all() следующим образом:
var liks = [];
var tempLiks = [];
db.collection('users')
.where('uid', '==', uid)
.get()
.then(function(querySnapshot) {
// Here the Promise returned by the get() method is fulfilled, so you do have the results of the query and you do'nt need to use setTimeout
var queries = [];
querySnapshot.forEach(function(doc) {
tempLiks = doc.data().yourLikes;
//We push each query to the queries array
queries.push(
db
.collection('memeInfo')
.where('usersLiked', '==', doc.data().uid)
.get()
);
});
//Then we call Promise.all()
return Promise.all(queries);
})
.then(function(results) {
//As explained in the doc "The returned promise is fulfilled with an array containing all the values of the iterable passed as argument (the queries array)."
//So result is an array of QuerySnapshots, since the get() method returns a QuerySnapshot
//Do whatever you want with the array
console.info(results);
results.forEach(function (querySnapshot) {
querySnapshot.forEach(function (doc) {
//.....
});
});
});
Как бы вы использовали promise.all() в этой функции? Могу ли я просто добавить его после .then()?