Swift Firebase queryOrdered,QueryQual无法在比子节点更深的节点上进行排序和查找

Swift Firebase queryOrdered,QueryQual无法在比子节点更深的节点上进行排序和查找,swift,firebase,firebase-realtime-database,indexing,Swift,Firebase,Firebase Realtime Database,Indexing,我看了几篇StackOverflow文章,介绍了如何通过将几个节点深的子值相等来获取数据值 在数据库结构中: 查询ref.child(“user_id”).orderByChild(“name”).equalTo(“objective-c”)用于提取具有特定uid的子对象 在中,数据库结构为: 查询ref.child('users').orderByChild('name').equalTo('johndoe')能够提取相应的子级 在这两种情况下,排序和等值都由孙子负责。然而,在我的例子中,数据

我看了几篇StackOverflow文章,介绍了如何通过将几个节点深的子值相等来获取数据值

在数据库结构中:

查询
ref.child(“user_id”).orderByChild(“name”).equalTo(“objective-c”)
用于提取具有特定uid的子对象

在中,数据库结构为:

查询
ref.child('users').orderByChild('name').equalTo('johndoe')
能够提取相应的子级

在这两种情况下,排序和等值都由孙子负责。然而,在我的例子中,数据库结构有点不同。我想通过几层深的子属性进行索引。结构如下:

因此,我尝试运行以下查询:
authenticatedUsersReference.queryOrdered(byChild:fcmTokenKey.queryEqual(toValue:fcmToken.observeSingleEvent(of:.value)
,我的快照返回了
nil
。但是当我运行
authenticatedUsersReference.queryOrdered(byChild:fcmTokenKey.observe(.value)
时,我看到快照值是由fcmtoken排序的
authenticatedUsersReference
指向
Database.Database().reference().child(“人员/已验证”)
。我还更新了在服务器端进行索引的规则。据我所知,即使深度发生变化,概念也应该保持不变,那么我遗漏了什么导致我的查询返回
nil

"people": {
      "users": {
        "authenticated": {
          "$userName": {
            ".indexOn": ["fcmToken"]
          }
        }
      }
    }

您正在为
fcmToken
$userName
上定义索引。这允许您查询特定的
$userName
节点的
fcmToken
属性

但是,您的代码会在所有用户中查询其
fcmToken
属性,该属性不存在索引。因此,第一个解决方案是,您需要在要查询的位置上定义索引,以此类推
authenticated

"people": {
  "users": {
    "authenticated": {
      ".indexOn": ["fcmToken"]
    }
  }
}

现在,上面在正确的位置创建了索引,让我们看看它在索引中放置了什么值

对于
authenticated
的每个子节点,上面获取其
fcmToken
属性,并将该属性的值放入索引中。但是如果我们查看您的JSON,
authenticated
的子节点没有direct子属性
fcmToken
。所以索引中没有值,这就解释了为什么查询没有结果

相反,您在(固定)路径上有一个子属性:
stats/fcmToken
,因此您也应该在索引定义中使用它

因此,总的来说:

"people": {
  "users": {
    "authenticated": {
      ".indexOn": ["stats/fcmToken"]
    }
  }
}
根据该定义,索引中存在正确的值,您可以通过以下方式查询:

authenticatedUsersReference
  .queryOrdered(byChild: "stats/fcmToken")
  .queryEqual(toValue: fcmToken)
编辑: 获取此快照后,与获取密钥相关的所有方法都将不再有用,因为根引用是经过身份验证的。所以,
snapshot.ref
snapshot.key
都会指向这个

大多数这类问题都需要能够获取与检索到的孩子相关的UID。(例如,如果firToken对于多个用户是相同的,则可以是多个)

实现这一点的最简单方法是,不使用
jsondeconder
s进行复杂和不必要的解析,如下所示:

{(snapshot) in
    guard let value = snapshot.value as? [String: Any] { return }
    let uids = Array(snapshot.keys)
    print("UIDs for with matching FCMToken are: \(uids)")
    //UIDs for with matching FCMToken are: ["parthv21", "anotherUserName"]
}

谢谢,这给了我预期的快照。但是我如何获得用户名呢<在这种情况下,代码>零件HV21?snapshot.ref.key为我提供了
authenticated
:/snapshot.value具有第一个key
parthv21:{}
的整个json。有没有一种方法可以在不解码snapshot.value的情况下使用可编码对象访问此快照?“谢谢,这将为我提供所需的快照。”->在这种情况下,请向上投票。对于其他问题:这些问题取决于您的代码,您没有共享这些代码。我建议为此提出一个新的问题(规则可能不再适用,因为这个问题已经在这里解决了)。是的,等等,我已经解决了。将接受您的答案,并稍作修改,以包含所需的额外内容,因为在大多数问题中,人们希望关联uid密钥。此外,Frank,由于您对firebase了解很多,请查看:。谢谢!