Загадка пожарного магазина! Использование .where() для массивов и строк

Я пытаюсь использовать функциональность .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), это было бы очень признательно.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы должны использовать оператор 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()?

Darrow Hartman 03.06.2019 20:49

Другие вопросы по теме