swift - queryOrdered 并不总是以正确的顺序返回 tableViewCell 上的数据

标签 swift uitableview firebase-realtime-database notifications timestamp

我现在正在尝试根据时间戳对通知页面上的数据从新到旧进行排序 - 当我运行它时,有时它的顺序是正确的,但有时它是随机且不正确的。如果我可以添加任何内容以确保它始终顺利运行,请告诉我,提前谢谢您:)

我的 firebase JSON 结构是:

"notifications" : {
  "BlP58dSQGCUBwhst91yha43AQu42" : {
    "-LeNCQJ6nUSR1263iKyj" : {
      "from" : "FRuuk20CHrhNlYIBmgN4TTz3Cxn1",
      "timestamp" : 1557331817,
      "type" : "true"
    },
    "-LeNCRwNpNaXm2qhYPpu" : {
      "from" : "FRuuk20CHrhNlYIBmgN4TTz3Cxn1",
      "timestamp" : 1557331824,
      "type" : "true"
    },
    "BlP58dSQGCUBwhst91yha43AQu42-FRuuk20CHrhNlYIBmgN4TTz3Cxn1" : {
      "from" : "FRuuk20CHrhNlYIBmgN4TTz3Cxn1",
      "timestamp" : 1557331811,
      "type" : "false"
    }
  },

我的代码:

func observeNotification(withId  id: String, completion: @escaping (Notifications) -> Void) {
    REF_NOTIFICATION.child(id).queryOrdered(byChild: "timestamp").observe(.childAdded, with: { snapshot in
        if let dict = snapshot.value as? [String: Any] {
            let newNoti = Notifications.transform(dict: dict, key: snapshot.key)
            completion(newNoti)
        }
    })
}

编辑:

然后在NotificationViewController中调用该函数,如下所示:

func loadNotifications() {
    guard let currentUser = Api.User.CURRENT_USER else { return }
    Api.Notification.observeNotification(withId: currentUser.uid , completion: { notifications in
        guard let uid = notifications.from else { return }
        self.fetchUser(uid: uid, completed: {
            self.notifications.insert(notifications, at: 0)
            self.tableView.reloadData()
        })
    })
}

并且在viewDidLoad中调用loadNotifications()

更新:

尝试使用“for child in snapshot.children”来执行此操作,但通知页面上不再显示任何内容

func observeNotification(withId  id: String, completion: @escaping (Notifications) -> Void) {
    REF_NOTIFICATION.child(id).observe(.value, with: { snapshot in
        for child in snapshot.children {
            let snap = child as! DataSnapshot
            let key = snap.key
            let notificationOrder = self.REF_NOTIFICATION.child(key).queryOrdered(byChild: "timestamp")

            notificationOrder.observeSingleEvent(of: .value, with: { snapshot in
                if let dict = snapshot.value as? [String: Any] {
                    print(dict)
                    let newNoti = Notifications.transform(dict: dict, key: snapshot.key)
                    completion(newNoti)
                }
            })
        }
    })
  }
}

最佳答案

您从 Firebase 返回的 DataSnapshot 包含三种类型的信息:

  1. 与查询匹配的每个子项的键。
  2. 与查询匹配的每个子项的值。
  3. 查询子项结果的顺序。

当您将整个结果转换为字典时(dict = snapshot.value as? [String: Any]),只有键和值的位置。所以 children 的顺序就丢失了。

要维持子节点的顺序,请循环遍历 snapshot.children 的查询结果,如 listening for lists of data with a value event 的文档中所示。 .

关于swift - queryOrdered 并不总是以正确的顺序返回 tableViewCell 上的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56045043/

相关文章:

ios - 我们如何在 iOS 中使用两个 SWRevealViewController?

ios - 如何异步加载 CollectionView 单元格图像?

ios - Swift-在UITableView中添加单元格

java - 如何将数据与身份验证数据一起存储在 Firebase 中

javascript - 删除多个数据库,仅注册一个云函数

android - Firebase 实时数据库 addValueEventListener

iOS:如何通过单击 tabBarItem 的第 3 个索引来打开 tabBarItem 的第 0 个索引

ios - 我需要在 deinit 中删除 UIGestureRecognizer 吗?

ios - 从 UITableViewCell 禁用 subview isHighlighted

ios - 如果文件管理器显示文档存在,则更新/更改 UITableView 附件