swift Firebase queryOrdered、queryEqual不适用于在比孙节点更深的节点上进行排序和查找

apeeds0o  于 2024-01-05  发布在  Swift
关注(0)|答案(1)|浏览(125)

我看了几篇StackOverflow的文章,关于如何通过等同于几个节点深度的子值来获得数据值。
在Firebase数据库中-如何执行前缀查询,数据库的结构是:
x1c 0d1x的数据
并且查询ref.child("user_id").orderByChild("name").equalTo("objective-c")用于拉出具有特定UID的子。
Firebase search by child value中,数据库结构是:



并且查询ref.child('users').orderByChild('name').equalTo('John Doe')能够拉出适当的子。
在这两种情况下,排序和相等都是在孙子上进行的。然而,在我的情况下,数据库结构有点不同。我想通过几层深的子属性进行索引。结构是:



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

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

字符串

c7rzv4ha

c7rzv4ha1#

您正在为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)

编辑:

一旦你得到了这个快照,所有与获取密钥相关的方法都将不再有用,因为根引用是authenticated/。所以snapshot.refsnapshot.key都将指向它。
大多数这类问题都需要能够获取与检索到的子项关联的UID。(例如,如果多个用户的firToken相同,则可以不止一个)
实现这一点的最小方法,而不需要使用JSONDecoder 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: ["userId", "otherUserId"]
}

相关问题