Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Firebase&swift使用.indexOn对数据快照进行排序_Swift_Firebase_Firebase Realtime Database - Fatal编程技术网

Firebase&swift使用.indexOn对数据快照进行排序

Firebase&swift使用.indexOn对数据快照进行排序,swift,firebase,firebase-realtime-database,Swift,Firebase,Firebase Realtime Database,我是Firebase/swift的新手,我正在尝试使用.indexOn对服务器上的一组节点进行排序。我已经搜索了SO和文档来编写规则,但我正在努力寻找swift代码使用索引的正确格式 我的假设是,当我使用.indexOn规则时,返回的快照使用该索引对结果进行排序。通过在swift中使用.queryOrderedByChildtitle,我否定了创建索引对服务器端性能的好处。如果这个假设不正确,请纠正我 以下是我的Firebase DB结构的简化片段: { "users": { "Gk

我是Firebase/swift的新手,我正在尝试使用.indexOn对服务器上的一组节点进行排序。我已经搜索了SO和文档来编写规则,但我正在努力寻找swift代码使用索引的正确格式

我的假设是,当我使用.indexOn规则时,返回的快照使用该索引对结果进行排序。通过在swift中使用.queryOrderedByChildtitle,我否定了创建索引对服务器端性能的好处。如果这个假设不正确,请纠正我

以下是我的Firebase DB结构的简化片段:

{
  "users": {
    "GkdjgdBJh1TxuAzIPezLWRouG9f2": {
      "messages": {
        "-KM0crettRl-RLQQdmMQ": {
          "body": "Anyone want a bit of body string?",
          "title": "5 Another title string",
        },
        "-KM0dhkChY6ZQ2QzuPlC": {
          "body": "This is a short body string",
          "title": "1 A lovely title string",
        },
        "-FQ0dhkChY6ZQ2Qzu3RQv": {
          "body": "Short and sweet body string",
          "title": "3 I should be in the middle",
        }
      }
    }
  }
}
以下是我的规则:

{
    "rules": {
        ".read": true,
        ".write": true,
        "users": {
              "$userid": {
                    "messages": {
                          ".indexOn": ["title"]
                    }
              }
        }
    }
}
这是我的swift代码:

if let user = FIRAuth.auth()?.currentUser {
    // user is logged in

    // *** I think this is the line with the issue ***
    FIRDatabase.database().reference().child("users").child(user.uid).child("messages").observeEventType(.Value, withBlock: { (snapshot) in
    messageArray = []

        if let dictionaryOfMessages = snapshot.value as? [String: AnyObject] {
            for messageKey in dictionaryOfMessages.keys {
                messageArray.append(Message(json: JSON(dictionaryOfMessages[messageKey]!)))
                // set the messageId
                messageArray[messageArray.count - 1].messageId = messageKey
            }
        }
        // return the data to the VC that called the function
        success(messages: messageArray)
    }) { (error) in
        // Handle the Error
    }
} else {
    // return some generic messages about logging in etc.
}
任何关于如何修改Swift代码以使用索引或更正错误索引的建议都将非常有用。

当您请求数据时,您需要使用queryOrderedByChild,并像以前一样在规则中有一个键。这里有一个例子

Firebase文档

下面的示例演示了如何检索按明星数排序的用户热门帖子列表:

// My top posts by number of stars
let myTopPostsQuery = (ref.child("user-posts").child(getUid())).queryOrderedByChild("starCount")
此查询根据用户ID从数据库中的路径检索用户的帖子,用户ID按每篇帖子收到的星星数排序。这种使用ID作为索引键的技术称为数据扇出

对queryOrderedByChild方法的调用指定按其排序结果的子键。在这种情况下,文章按每个文章中starCount子级的值排序。有关其他数据类型的排序方式的详细信息,请参见查询数据的排序方式

请点击链接了解更多详情

当您请求数据时,您需要使用queryOrderedByChild,并且在您的规则中有一个密钥。这里有一个例子

Firebase文档

下面的示例演示了如何检索按明星数排序的用户热门帖子列表:

// My top posts by number of stars
let myTopPostsQuery = (ref.child("user-posts").child(getUid())).queryOrderedByChild("starCount")
此查询根据用户ID从数据库中的路径检索用户的帖子,用户ID按每篇帖子收到的星星数排序。这种使用ID作为索引键的技术称为数据扇出

对queryOrderedByChild方法的调用指定按其排序结果的子键。在这种情况下,文章按每个文章中starCount子级的值排序。有关其他数据类型的排序方式的详细信息,请参见查询数据的排序方式

请点击链接了解更多详情


首先,您需要遵循Jad的答案并指定接收子节点的顺序。单个列表可以有许多索引,您需要指定此特定查询的顺序

指定顺序后,Firebase数据库将返回一个快照,其中包含与查询匹配的节点以及有关这些节点在结果中出现顺序的信息

但是字典里没有关于孩子顺序的任何信息。因此,当代码将快照转换为字典时,有关顺序的所有信息都将丢失:

if let dictionaryOfMessages = snapshot.value as? [String: AnyObject] {
因此,最好使用快照的内置方法迭代子节点:

for child in snapshot.children {
  let key = child.key as String
  print(key)
  messageArray.append(Message(json: JSON(child.value)))  // JSON handling via SwiftyJSON
  // set the messageId
  messageArray[messageArray.count - 1].messageId = key
}

首先,您需要遵循Jad的答案并指定接收子节点的顺序。单个列表可以有许多索引,您需要指定此特定查询的顺序

指定顺序后,Firebase数据库将返回一个快照,其中包含与查询匹配的节点以及有关这些节点在结果中出现顺序的信息

但是字典里没有关于孩子顺序的任何信息。因此,当代码将快照转换为字典时,有关顺序的所有信息都将丢失:

if let dictionaryOfMessages = snapshot.value as? [String: AnyObject] {
因此,最好使用快照的内置方法迭代子节点:

for child in snapshot.children {
  let key = child.key as String
  print(key)
  messageArray.append(Message(json: JSON(child.value)))  // JSON handling via SwiftyJSON
  // set the messageId
  messageArray[messageArray.count - 1].messageId = key
}

我对你的问题不是很清楚。添加索引后是否会对性能产生负面影响?或者你的结果有问题吗?嗨@FrankvanPuffelen-记住我是个新手,所以我有点困惑。我的结果目前按存储在Firebase中的顺序显示,而不是按索引排序。我在文档中读到,最好使用indexOn在服务器上进行排序。因此,indexOn决定提前进行排序。我的数据集可能会变得非常大,因此我无法在现阶段对性能进行评论。好的,明白了。我会写一个答案。对于未来的问题,最好只提及出错的部分。如果数组中的元素的顺序与您期望的不一致,则使用索引的性能影响是irrelevant@FrankvanPuffelen-谢谢。我明白你的意思。但是,由于我是一个困惑的新手,我不确定我的indexOn是否错误,或者即使indexOn正确就位,我也不确定是否仍应该使用.queryOrderedByChild以某种方式查看预期排序顺序的结果。我想我的问题可能是:有一个.I吗

JSON规则中的ndexOn消除了在检索排序数据时使用.queryOrderedByChild的需要?最后一个问题确实非常清楚。答案是否定的。答案如下。Jad是第一个,但你可能也需要我的。我不太清楚你的问题。添加索引后是否会对性能产生负面影响?或者你的结果有问题吗?嗨@FrankvanPuffelen-记住我是个新手,所以我有点困惑。我的结果目前按存储在Firebase中的顺序显示,而不是按索引排序。我在文档中读到,最好使用indexOn在服务器上进行排序。因此,indexOn决定提前进行排序。我的数据集可能会变得非常大,因此我无法在现阶段对性能进行评论。好的,明白了。我会写一个答案。对于未来的问题,最好只提及出错的部分。如果数组中的元素的顺序与您期望的不一致,则使用索引的性能影响是irrelevant@FrankvanPuffelen-谢谢。我明白你的意思。但是,由于我是一个困惑的新手,我不确定我的indexOn是否错误,或者即使indexOn正确就位,我也不确定是否仍应该使用.queryOrderedByChild以某种方式查看预期排序顺序的结果。我想我的问题可能是:在规则JSON中使用.indexOn是否就不需要在检索排序数据时使用.queryOrderedByChild?最后一个问题确实非常清楚。答案是否定的。答案如下。Jad是第一个,但你可能也需要我的。谢谢-我想我的困惑是因为我在文档中读到,在规则中添加索引是个好主意。因此,我假设使用索引而不是.queryOrderedByChild。既然@FrankVanPuffelen已经确认了你的答案是正确的,我会听从你的建议继续前进。我想我的困惑是因为我在文档中读到,在规则中添加索引是个好主意。因此,我假设使用索引而不是.queryOrderedByChild。既然@FrankVanPuffelen已经确认了你的答案是正确的,我会听从你的建议继续前进。许多人感谢您确认Jad的答案,并感谢您提供有关词典的提示。如果客户端必须在结果到达后对其进行排序,我仍然不确定添加索引的客户端性能优势来自何处,但我将继续讨论:-客户端没有对结果进行排序,它只是按照正确的顺序返回结果。字典是无序的,因此通过转换为字典,您就放弃了所有的排序。@FrankvanPuffelen根据OP的代码,如果我尝试使用Swift库而不是REST API读取数据库,我是否还需要修改Firebase实时数据库中的规则,以提高queering的性能?感谢您确认Jad的答案并提供有关词典的提示。如果客户端必须在结果到达后对其进行排序,我仍然不确定添加索引的客户端性能优势来自何处,但我将继续讨论:-客户端没有对结果进行排序,它只是按照正确的顺序返回结果。字典是无序的,因此通过转换为字典,您就放弃了所有的排序。@FrankvanPuffelen根据OP的代码,如果我尝试使用Swift库而不是REST API来读取数据库,我是否还需要修改Firebase实时数据库中的规则,以便queering的性能得到提高?