簡體   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