当前位置: 首页 > 面试题库 >

Firebase按顺序获取数据

姚信鸥
2023-03-14
问题内容

我正在使用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]

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
 }
}

工艺流程

  1. 遍历快照中的每个孩子

  2. 将子级转换为FIRDataSnapshot,因此它不是元素

  3. 获取特定子项的值以从中访问属性

  4. 遵循NSDictionary原则为孩子添加相应的代码。

为什么这个解决方案是可靠的

以正确的顺序接收快照非常简单。我遇到的问题是在获得时要以正确的顺序获取数据snapshot.value。该解决方案解决了该问题,因为仅在循环排序的快照子项时才访问每个子项的值。这使子级的顺序仍然受快照控制。

我也喜欢这种snapshot.value方法,[String: AnyObject]因为它非常接近Swift中Firebase实施的旧功能:简单而干净。我实际上认为,以这种方式使用NSDictionary实际上是从长远来看节省时间的一种方式,因为它绝不是冗长的。



 类似资料:
  • {1,2,3}的幂集是: {{}, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}} 我有一个java字符串数组, 如何按数学顺序打印此数组的幂集?(我试过位操作方法,它没有按该顺序给出解决方案!) 我的位操作方法!没有给出所需的结果!

  • 如果我使用,是否总是100%保证我将获得的数据是从最早到最新的排序,或者键是按照词典的顺序排列的?

  • 问题内容: 例 删除 后如何保持按键顺序?我希望它是0..1..2..3..etc 问题答案: 您无法更改密钥的名称,没有用于执行此操作的API。如果要更改密钥的名称,则需要将该特定对象复制到另一个位置,更改名称并删除旧的密钥。但是在Firebase中无法更改密钥名称。

  • 在一个<代码>中

  • 问题内容: 这是一个快速的为您服务的: 我有一个ID列表,我想用它返回QuerySet(或数组(如果需要的话)),但是我想保持该顺序。 谢谢 问题答案: 我认为你不能在数据库级别强制执行该特定命令,因此你需要使用python来代替。 这将建立一个以id为键的对象字典,因此在建立排序列表时可以轻松检索它们。

  • 问题内容: 我在mysql排序中寻找一些调整,我通常从表中选择记录,然后按Name(varchar)ASC排序记录, 但编号始终是第一位的 这是我的问题的一些示例( 注意。mysql首先用0-9排序记录 ) 我想要的是字母顺序,然后是数字 所需的输出 问题答案: 使用以下子句: