我正在使用Firebase,直到最近我都没有按字母顺序获取数据的问题。我从来没有使用过查询,我总是只使用数据快照并逐一对其进行排序。最近,在 snapVal中 ,数据并不总是按字母顺序 排列 。如何做到这一点,以便获得按字母顺序排序的数据的snapVal,就像数据库快照中的快照一样?
真实示例:有4条消息,id1-id4(按此顺序)。它们包含消息“ 1”-“ 4”。快照看起来正确。但是snapVal(snapshot.value)看起来像这样:
["id2": { DATE = "10/20/16"; "FIRST_NAME" = first; ID = userID; "LAST_NAME" = last; MESSAGE = 2; TIME = "8:12 PM"; }, "id4": { DATE = "10/20/16"; "FIRST_NAME" = first; ID = userID; "LAST_NAME" = last; MESSAGE = 4; TIME = "8:12 PM"; }, "id1": { DATE = "10/20/16"; "FIRST_NAME" = first; ID = userID; "LAST_NAME" = last; MESSAGE = 1; TIME = "8:12 PM"; }, "id3": { DATE = "10/20/16"; "FIRST_NAME" = first; ID = userID; "LAST_NAME" = last; MESSAGE = 3; TIME = "8:12 PM"; }]
快照如下所示:
["id1": { DATE = "10/20/16"; "FIRST_NAME" = first; ID = userID; "LAST_NAME" = last; MESSAGE = 1; TIME = "8:12 PM"; }, "id2": { DATE = "10/20/16"; "FIRST_NAME" = first; ID = userID; "LAST_NAME" = last; MESSAGE = 2; TIME = "8:12 PM"; }, "id3": { DATE = "10/20/16"; "FIRST_NAME" = first; ID = userID; "LAST_NAME" = last; MESSAGE = 3; TIME = "8:12 PM"; }, "id4": { DATE = "10/20/16"; "FIRST_NAME" = first; ID = userID; "LAST_NAME" = last; MESSAGE = 4; TIME = "8:12 PM"; }]
要获取snapVal,请使用以下代码:
if let snapVal = snapshot.value as? [String: AnyObject] { // Comes out of order.. }
澄清:
快照(最终结果正确无误):
Snap (CHAT) { id1 = { DATE = "10/20/16"; "FIRST_NAME" = first; ID = userID; "LAST_NAME" = last; MESSAGE = 1; TIME = "8:12 PM"; }; id2 = { DATE = "10/20/16"; "FIRST_NAME" = first; ID = userID; "LAST_NAME" = last; MESSAGE = 2; TIME = "8:12 PM"; }; id3 = { DATE = "10/20/16"; "FIRST_NAME" = first; ID = userID; "LAST_NAME" = last; MESSAGE = 3; TIME = "8:12 PM"; }; id4 = { DATE = "10/20/16"; "FIRST_NAME" = first; ID = userID; "LAST_NAME" = last; MESSAGE = 4; TIME = "8:12 PM"; }; }
这是print(snapVal.keys)inside 的输出if let snapVal = snapshot.value as? [String: AnyObject]:
print(snapVal.keys)
if let snapVal = snapshot.value as? [String: AnyObject]
LazyMapCollection<Dictionary<String, AnyObject>, String>(_base: ["id2": { DATE = "10/20/16"; "FIRST_NAME" = first; ID = userID; "LAST_NAME" = last; MESSAGE = 2; TIME = "8:12 PM"; }, "id4": { DATE = "10/20/16"; "FIRST_NAME" = first; ID = userID; "LAST_NAME" = last; MESSAGE = 4; TIME = "8:12 PM"; }, "id1": { DATE = "10/20/16"; "FIRST_NAME" = first; ID = userID; "LAST_NAME" = last; MESSAGE = 1; TIME = "8:12 PM"; }, "id3": { DATE = "10/20/16"; "FIRST_NAME" = first; ID = userID; "LAST_NAME" = last; MESSAGE = 3; TIME = "8:12 PM"; }], _transform: (Function))
我的代码:
self.firebase.child("Chats").child(chatID).queryOrderedByKey().observeSingleEvent(of: .value, with: { (snapshot) in print(snapshot) if let snapVal = snapshot.value as? [String: AnyObject] { print(snapVal) for c in snapVal { print("checking Message as child") let message = c.value["MESSAGE"] as? String let fn = c.value["FIRST_NAME"] as? String let ln = c.value["LAST_NAME"] as? String let USER_ID = c.value["ID"] as? String if let userID = USER_ID { if let msg = message { if let firstName = fn { if let lastName = ln { let username = "\(firstName) \(lastName)" self.addMessage(userID, text: msg, name: username) print("Message added! \nMessage Info:") print("User ID: \(userID)") print("text: \(msg)") print("Username: \(username)") } else { print("LN did not pass") } } else { print("FN did not pass") } } else { print("Msg did not pass") } } else { print("User ID did not pass") } } } })
解决方案 :经过非常广泛的搜索和尝试后,问题仍然存在,一旦将快照转换为snapVal(snapshot.value),该顺序通常会重新排列。我的(有效)解决方案:
for child in snapshot.children { let child = child as! FIRDataSnapshot if let childVal = child.value as? [String: AnyObject] { let childMessage = childVal["MESSAGE"] as! String // more code for each child. This child might be a post of a sort, which you can access properties of in a way like I did in the line above } }
工艺流程 :
遍历快照中的每个孩子
将子级转换为FIRDataSnapshot,因此它不是元素
获取特定子项的值以从中访问属性
遵循NSDictionary原则为孩子添加相应的代码。
为什么这个解决方案是可靠的
以正确的顺序接收快照非常简单。我遇到的问题是在获得时要以正确的顺序获取数据snapshot.value。该解决方案解决了该问题,因为仅在循环排序的快照子项时才访问每个子项的值。这使子级的顺序仍然受快照控制。
snapshot.value
我也喜欢这种snapshot.value方法,[String: AnyObject]因为它非常接近Swift中Firebase实施的旧功能:简单而干净。我实际上认为,以这种方式使用NSDictionary实际上是从长远来看节省时间的一种方式,因为它绝不是冗长的。
[String: AnyObject]