Swift 从 childByAutoID 检索 Firebase 值

Swift Retrieve Firebase Value from childByAutoID

我在这里阅读了大约一百篇关于处理来自 Firebase 的实时数据库的“childByAutoId”子项的值的帖子......但我还没有找到任何可以解释我正在尝试做的事情的东西所以我想我终于忍不住问了。

首先是数据库结构:

let database = Database.database().reference(withPath: "messages")
let db1 = database.child("sender").child("receiver").childByAutoId()

非常简单。然后我想检索那个 autoID 的值。

db1.observeSingleEvent(of: .value, with: { snapshot in
            guard let value = snapshot.value as? [String: Any] else{
                completion(.failure(DatabaseError.failedToFetch))
                print("GetAll Failed")
                return
            }

...returns“failedToFetch”错误,同时:

database.child("sender").child("receiver").observeSingleEvent(of: .value, with: { snapshot in
            guard let value = snapshot.value as? [String: Any] else{
                completion(.failure(DatabaseError.failedToFetch))
                print("GetAll Failed")
                return
            }

...这是同一件事,只是不包括 childByAutoId returns:

"-MrdAxlUKHvJWjtSQe7X": {
    body = "cookies";
    createdat = 1640294767943;
    msgId = "-MrdAxlUKHvJWjtSQe7X";
    name = glynis;
    receiverUid = LKJHdhkjhkjsh;
    senderUid = LAKSjksljlkajlk;
}

所以现在数据正在传入...但是当我尝试获取“-MrdAxlUKHvJWjtSQe7X”(自动生成的密钥)的值时:

let things: [Thing] = value.compactMap({ dictionary in
                guard let name = value["name"] as? String,
                    let msgId = value["msgId"] as? String,
                    let body = value["body"] as? String,
                    let receiverUid = value["receiverUid"] as? String,
                    let senderUid = value["senderUid"] as? String,
                    let createdat = value["createdat"] as? String,
                    let dated = value["dated"] as? String,)else {
                            return nil
                    }

然后我做了一个:

guard !things.isEmpty else {
                    print("thing are empty")
                    return
                }

它们是空的(即使肯定填充了“值”。)所以我的问题是如何正确检索生成的密钥 (childByAutoId) 的值?

我发现的一些问题:

  1. value.compactMap( 中的大部分字段在其正上方的快照中没有匹配的 属性。例如。 createdatvalue["created"]不一样,快照中没有属性tId

  2. 类型需要匹配才能使 as? String 转换工作。您的 createdat 值是一个很长的数字(可能是自纪元以来的毫秒数),因此将其转换为字符串会导致 nil。您应该将其转换为 long/number 值,或通过调用 String 函数进行转换,如下所示:Convert Int to String in Swift


根据您的编辑...

此代码:

database.child("sender").child("receiver").observeSingleEvent(of: .value, with: { snapshot in

从您的数据库中读取整个 sender/receiver 节点,其中包含一个或多个具有自动生成键的子节点,然后是每个子节点下的属性。

当你这样做时:

value = snapshot.value as? [String: Any]

这将 value 设置为 dictionary/map,顶级键为 childByAutoId。然后,当您访问 value["-MrdAxlUKHvJWjtSQe7X"] 时,您会得到一个具有该子节点属性的 map/dictionary。

您还可以 loop over the child nodes 使用类似以下内容的快照:

for child in snapshot.children {
    let snap = child as! DataSnapshot //downcast

    let dict = snap.value as! [String: Any] // get properties of child node
    let msg = dict["body"] as! String
}