简体   繁体   English

消防局难题! 对数组和字符串使用.where()

[英]Firestore Conundrum! Using .where() for arrays and strings

I am attempting to use the .where() functionality of firestore to detect if a certain string is in an array in the database. 我正在尝试使用firestore的.where()功能来检测数据库中数组中是否存在某个字符串。 I have tried manipulating the first parameter of the function by adding brackets and other things to signify parts of an array to no avail. 我试图通过添加方括号和其他东西来操纵该函数的第一个参数,以表示无用的数组部分。

//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.log(liks)
              }
            })
          })
      },500)

If anyone has a solution to querying to see if individual values are in arrays without using a for loop forever (I will have possibly thousands of values in the usersLiked array), that would be much appreciated. 如果任何人都可以通过查询解决方案来查看单个值是否在数组中而无需永远使用for循环(我可能在usersLiked数组中可能有成千上万个值),那将不胜感激。

You should use the array_contains operator to filter based on array values, see https://firebase.google.com/docs/firestore/query-data/queries#array_membership . 您应该使用array_contains运算符基于数组值进行过滤,请参阅https://firebase.google.com/docs/firestore/query-data/queries#array_membership

Therefore you have to adapt your code as follows: 因此,您必须按以下方式修改代码:

//....
db.collection("memeInfo").where("usersLiked", "array-contains", doc.data().uid)
        .get()
        .then(function(querySnapshot) {...})

Extra remark: using setTimeout() for managing the asynchronous aspect of the queries to Firestore is not a correct approach (there is no assurance that the query will be done in less than 500 ms). 额外说明:使用setTimeout()管理对Firestore的查询的异步方面不是正确的方法(无法保证查询将在500毫秒内完成)。 You should manage the asynchronicity through the promises returned by the get() method. 您应该通过get()方法返回的promise管理异步性。 In particular, since you are firing several queries in parallel (through your loops), you need to use Promise.all() . 特别是,由于要并行(通过循环)触发多个查询,因此需要使用Promise.all()


UPDATE following your comment. 发表评论后更新 You could use Promise.all() as follows: 您可以按如下方式使用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.log(results);
    results.forEach(function (querySnapshot) {
        querySnapshot.forEach(function (doc) {
            //.....
        });
    });
  });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM