Firebase queryOrderedByChild queryEqualToValue无法正常工作

时间:2016-07-03 11:19:31

标签: firebase firebase-realtime-database

没有任何运气让我的iOS项目查询我的玩家朋友高分:

private func checkFriendsScores(fbid: Int64)
{
    let users = ref.child("users")
    let fbidQuery = users.queryOrderedByChild("FBID")
    let friendIdNumber = String(fbid)
    let queryFriend = fbidQuery.queryEqualToValue(friendIdNumber)
    queryFriend.observeSingleEventOfType(.Value) { [unowned self](snapshot: FIRDataSnapshot!) in
        self.updateFriendsScores(fbid, data: snapshot)
    }
}

该代码编译并运行正常,应用程序的其他部分正在运行。查询应找到具有给定FBID的朋友,然后触发updateFriendScores函数,但该块永远不会执行。

数据如下:

{
  "users" : {
    "WhiPPS6AbcX6Xp2XQft29JZXR9G3" : {
      "BK035" : [ null, 540, 466, 515, 576, 748, 1019, 765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
      "FBID" : 10208576492403564
    },
    "d0fT2ge6ALa6QUKFcRApiqjaJd82" : {
      "BK018" : [ null, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646 ],
      "BK035" : [ null, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
      "FBID" : 1652501845074069
    },
    "o67iatcYLRbd2CrgkXGQWZNpmyC3" : {
      "BK018" : [ null, 816, 715, 642, 690, 864, 745, 899, 858, 847, 1045, 1148, 1002, 1119, 833, 1067, 0, 0, 0, 0, 0 ],
      "BK035" : [ null, 826, 620, 657, 673, 810, 1090, 804, 932, 931, 1079, 1007, 972, 1098, 1065, 927, 1582, 1195, 1265, 1366, 1548 ],
      "FBID" : 1094051894000026
    },
    "yW5ntKW9pwYvwm2EyvJlGSTzm0M2" : {
      "BK018" : [ null, 763, 457, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
      "BK035" : [ null, 645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
      "FBID" : 10153916083832933
    }
  }
}

有什么想法吗?

3 个答案:

答案 0 :(得分:3)

问题是您正在将Int64转换为String以执行查询。字符串12345与值12345

不同

推理是合理的,因为queryEqualToValue需要AnyObject,而Int64不符合AnyObject。

但是,将其转换为String会使其成为字符串,而不是值,并将其作为值存储在Firebase中。

所以解决方案是

a) Use Int values in general instead of converting to strings
b) Type conversion to an Int. let num = Int(fbid) and then 
       fbidQuery.queryEqualToValue(num)
c) Avoid the issue completely any store/retrieve those numbers as a string in Firebase

我正在使用c),因为从长远来看它只会使处理数据变得更加容易。

答案 1 :(得分:0)

正如我在您的数据中看到的那样,您没有将FBID保存为String,因此在执行queryEqualToValue时无需将其强制转换为字符串。

private func checkFriendsScores(fbid: Int64){
    let users = ref.child("users")
    let fbidQuery = users.queryOrderedByChild("FBID")
    let queryFriend = fbidQuery.queryEqualToValue(Int(fbid))
    queryFriend.observeSingleEventOfType(.Value, withBlock: { (snapshot) in
        let BK035 = snapshot.value!["BK035"] as! NSArray
        self.updateFriendsScores(fbid, data: snapshot)
    }) { (error) in
        print(error.localizedDescription)
    }
}

答案 2 :(得分:0)

问题原因是安全规则。这是适用于我的规则,注释显示我必须添加一行。

由于@Jay有一个很好的答案,有助于保持数据的合理性(虽然它不是问题的根本原因)我也投票了。

不提前发布安全规则的道歉。应该想到这一点。

// These rules grant write access to a "users" node matching the authenticated
// user's ID from the Firebase auth token; and read access to all "users" nodes
// Since we will look up our friends via their Facebook ID's we need to index on
// that value
{
  "rules": {
    "users": {
      ".read": "auth != null",       // <<< Had to add this line
      ".indexOn": "FBID",
      "$uid": {
        ".read": "auth != null",       // <<< This was not enough
        ".write": "$uid === auth.uid"
      }
    }
  }
}

请注意,之前我还有一行:

".indexOn": "FBID"

内部&#34; $ uid&#34;范围,并在客户端库回应出警告后表示记录未被编入索引,并建议将其移至&#34;用户&#34;之后,将其移至如上所示。范围。

这个警告让我看到了安全规则并导致修复。

感谢您的帮助。