简体   繁体   English

如何按顺序获取Firebase快照中的子级列表?

[英]How can I get a list of children in a Firebase snapshot in order?

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. 我正在开发一个应用程序,该应用程序记录用户何时停止滚动运动,将滚动的偏移量和经过的时间附加到本地数组,然后在用户关闭应用程序时将滚动历史记录上载到Firebase。

The data in Firebase is stored with an auto ID at the top. Firebase中的数据在顶部存储有一个自动ID。 Each scroll offset and elapsed time is then stored within its own auto ID child below the parent. 然后,每个滚动偏移量和经过时间都存储在其父级下方的自己的自动ID子级中。 In the Firebase web app, the children are in proper order. 在Firebase Web应用程序中,孩子的顺序正确。

I pull the data from Firebase like so: 我像这样从Firebase提取数据:

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? 有什么方法可以按预期顺序拉动Firebase子级? 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: 编辑:这是按所需顺序显示在Firebase Web应用程序中的数据:

在此处输入图片说明

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. 您将不得不使用children迭代快照,(我相信)可以确保维持子级的顺序。 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. 您可以通过从1..n在Firebase文档中添加数字字段来获得U,以便您可以使用基于升/降的查询。 The result will be your expected result 结果将是您的预期结果

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM