Ios 使用Swift的Firebase查询未按预期工作

Ios 使用Swift的Firebase查询未按预期工作,ios,json,swift,firebase,firebase-realtime-database,Ios,Json,Swift,Firebase,Firebase Realtime Database,我正在尝试查询我的Firebase数据库以查找特定名称或电子邮件的用户。我已经找到了几个例子来说明如何做到这一点,所有的例子似乎都比较容易理解,但没有一个像我预期的那样有效 下面是我的json数据的结构示例 { "allUsers" : { "uid0001" : { "userInfo" : { "email" : "firstName1.lastName1@email.com",

我正在尝试查询我的Firebase数据库以查找特定名称或电子邮件的用户。我已经找到了几个例子来说明如何做到这一点,所有的例子似乎都比较容易理解,但没有一个像我预期的那样有效

下面是我的json数据的结构示例

{
 "allUsers" : {
    "uid0001" : {                        
       "userInfo" : {
          "email" : "firstName1.lastName1@email.com",                  
          "firstName" : "firstName1",
          "lastName" : "lastName1",          
          "uid" : "uid0001"
          }
       },
    "uid0002" : {        
       "userInfo" : {
          "email" : "firstName2.lastName2@email.com",
          "firstName" : "firstName2",
          "lastName" : "lastName2",          
          "uid" : "uid0002"
          }
       }
    }    
}
下面是一个示例函数,介绍了我如何尝试查询数据库

func performQuery(forName queryText:String)
{
    let key = "firstName"

    let ref1 = firebaseDatabaseManager.allUsersRef.queryOrdered(byChild: queryText)
    let ref2 = firebaseDatabaseManager.allUsersRef.queryEqual(toValue: queryText, childKey: key)

        //ref.observeSingleEvent(of: .childAdded, with: {(snapshot) in
        ref1.observe(.childAdded, with: {(snapshot) in

            let userId = snapshot.key

            if let dictionary = snapshot.value as? [String: AnyObject]
            {
                if let userInfo = dictionary["userInfo"] as? [String:AnyObject]
                {
                    if
                        let email           = userInfo["email"]         as? String,
                        let firstName       = userInfo["firstName"]     as? String,
                        let lastName        = userInfo["lastName"]      as? String
                    {
                        let user = User.init(withFirst: firstName, last: lastName, userEmail: email, uid: userId)
                    }
                }
            }
        })
}
你可以看到这里有两个例子,我是如何构造ref的,还有两个例子,我是如何观察ref的,尽管我已经尝试了我能想到的所有可能的组合

如果我使用ref.observe(。。。。 无论queryText是否实际存在,该块都将为节点上的所有用户执行。 如果我使用的是ref.observeSingleEvent(of:。。。。 该块将为json结构中最顶层的用户执行

除此之外,我还尝试了几种完全不返回任何内容的引用变体

感谢您的帮助! 谢谢

尝试更换

let ref2 = firebaseDatabaseManager.allUsersRef.queryEqual(toValue: queryText, childKey: key)

然后打电话:

ref2.observe(.childAdded, with: {(snapshot) in

因为现在您不是在寻找某个用户,而是在寻找所有用户

您需要将
queryOrderedByChild:
queryqualtovalue:
组合起来以获得正确的结果:

let query = firebaseDatabaseManager.allUsersRef
    .queryOrdered(byChild: "userInfo/" + key)
    .queryEqual(toValue: queryText)

query.observe(.childAdded, ...

这个问题是Firebase结构(不必要地)太深

你所拥有的是

"allUsers" : {
    "uid0001" : {                        
       "userInfo" : {    <- This is the issue
          "email" : "firstName1.lastName1@email.com",                  
          "firstName" : "firstName1",
          "lastName" : "lastName1",          
          "uid" : "uid0001"
          }
       },
可能不需要将userInfo节点放在uid0001节点内

此外,您可能不需要将uid存储在节点中,也不需要将其用作密钥—当返回节点时,您始终可以从snapshot.key中为每个用户获取uid

也就是说,你实际上可以用a来做这件事,但在这种情况下似乎不需要它。(请参阅Frank的答案,因为它是问题中发布的结构的正确解决方案)

并使用我建议的结构查询特定的名字

let fName = "firstName1"
let queryAllUsersRef = allUsersRef.queryOrdered(byChild: "firstName")
                                  .queryEqual(toValue: fName)

//get all of the users with firstName1
queryRef.observeSingleEvent(of: .value, with: { snapshot in

      //snapshot may return more than one user with that first name
      //  so iterate over the results
      for snap in snapshot.children {
           let userSnap = snap as! FIRDataSnapshot //each user is it's own snapshot
           let userKey = commentSnap.key //the uid key of each user
           let userDict = userSnap.value as! [String:AnyObject] 
           let email = userDict["email"] as! String
           print("uid: \(userKey) has email: \(email)"
      }
   })
"allUsers" : {
    "uid0001" : {                        
        "email" : "firstName1.lastName1@email.com",                  
        "firstName" : "firstName1",
        "lastName" : "lastName1"
    }
}
let fName = "firstName1"
let queryAllUsersRef = allUsersRef.queryOrdered(byChild: "firstName")
                                  .queryEqual(toValue: fName)

//get all of the users with firstName1
queryRef.observeSingleEvent(of: .value, with: { snapshot in

      //snapshot may return more than one user with that first name
      //  so iterate over the results
      for snap in snapshot.children {
           let userSnap = snap as! FIRDataSnapshot //each user is it's own snapshot
           let userKey = commentSnap.key //the uid key of each user
           let userDict = userSnap.value as! [String:AnyObject] 
           let email = userDict["email"] as! String
           print("uid: \(userKey) has email: \(email)"
      }
   })