繁体   English   中英

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

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

我正在尝试使用firestore的.where()功能来检测数据库中数组中是否存在某个字符串。 我试图通过添加方括号和其他东西来操纵该函数的第一个参数,以表示无用的数组部分。

//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)

如果任何人都可以通过查询解决方案来查看单个值是否在数组中而无需永远使用for循环(我可能在usersLiked数组中可能有成千上万个值),那将不胜感激。

您应该使用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管理异步性。 特别是,由于要并行(通过循环)触发多个查询,因此需要使用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.log(results);
    results.forEach(function (querySnapshot) {
        querySnapshot.forEach(function (doc) {
            //.....
        });
    });
  });

暂无
暂无

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

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