I'm working on an app that records when a user stops a scroll motion, appends the offset of the scroll and an elapsed time to a local array, and then uploads the scroll history to Firebase when the user closes the app.
The data in Firebase is stored with an auto ID at the top. Each scroll offset and elapsed time is then stored within its own auto ID child below the parent. In the Firebase web app, the children are in proper order.
I pull the data from Firebase like so:
ghostref.queryOrderedByKey().queryLimited(toLast: UInt(1)).observe(.childAdded, with: { (snapshot) in
guard let ghostdict = snapshot.value as? [String:[String:String]] else {
print("failure")
return
}
var downloadedghostarray = [(cameray:Float, timeelapse:Double)]()
for key in ghostdict.keys {
downloadedghostarray.append((cameray: Float(ghostdict[key]!["cameray"]!)!, timeelapse: Double(ghostdict[key]!["timeelapse"]!)!))
}
}
While I get the data I need, it is not in the proper order. Is there any way to pull Firebase children in the expected order? Maybe I can order the snapshot's children by key as well?
EDIT: Here is the data as it appears in the Firebase web app in the desired order:
And here is the array that renders using the code above:
By iterating the node fields by key and organizing them by key, you're effectively randomizing the elements in your list. Hash-based dictionaries/maps don't guarantee that order is maintained.
You're going to have to iterate the snapshot using children , which (I believe) ensures that order of the children is maintained. This order should allow you to push them into another array whose order is ensured.
class func downloadAllMessages(forUserID: String, completion: @escaping ([Message]) -> Swift.Void, locationCompletion: @escaping (String) -> Swift.Void) {
if let userID = Helper.shared.driverLoggedInDetails.detail?.userid {
let currentUserID = "D\(userID)"
dbReference.child("users").child(currentUserID).child("conversations_list").child(forUserID).observeSingleEvent(of: .value) { (snapshot) in
if snapshot.exists() {
let data = snapshot.value as! [String: Any]
let location = data["location"]!
locationCompletion(location as! String)
dbReference.child("messages").child(location as! String).observe(.childAdded, with: { (snap) in
if snap.exists() {
let receivedMessages = snap.value as! [String: Any]
var messages1 = [Message]()
let type = MessageType.text
let text = (receivedMessages as NSDictionary).object(forKey: "text") as? String
let mmText = (receivedMessages as NSDictionary).object(forKey: "mmText") as? String
let messageType = (receivedMessages as NSDictionary).object(forKey: "messageType") as? Int
let fromID = (receivedMessages as NSDictionary).object(forKey: "senderId")as? String
let timestamp = (receivedMessages as NSDictionary).object(forKey: "timeStamp")as? Int
let isRead = (receivedMessages as NSDictionary).object(forKey: "read")as? Bool
let isvisible = UserDefaults.standard.object(forKey: "chatwindow") as? Bool
if fromID != currentUserID, isvisible ?? false {
dbReference.child("messages").child(location as? String ?? "").child(snap.key).child("read").setValue(true)
}
if fromID == currentUserID {
let message = Message.init(type: type, textEn: text ?? "", textMM: mmText ?? "", owner: .receiver, timestamp: timestamp ?? 0, isRead: isRead ?? false, isSuggested: messageType == -1 ? true : false)
messages1.append(message)
} else {
let message = Message.init(type: type, textEn: text ?? "", textMM: mmText ?? "", owner: .sender, timestamp: timestamp ?? 0, isRead: isRead ?? false, isSuggested: messageType == -1 ? true : false)
messages1.append(message)
}
completion(messages1)
}else {
// LoadingIndicator.shared.hide()
completion([])
}
})
// LoadingIndicator.shared.hide()
completion([])
}
}
}
}
U can get by adding a number field in the firebase document from 1..n, so that you can use query based on ascending/ descending. The result will be your expected result
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.