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) 的值?
我发现的一些问题:
您 value.compactMap(
中的大部分字段在其正上方的快照中没有匹配的 属性。例如。 createdat
与value["created"]
不一样,快照中没有属性tId
类型需要匹配才能使 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
}
我在这里阅读了大约一百篇关于处理来自 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) 的值?
我发现的一些问题:
您
value.compactMap(
中的大部分字段在其正上方的快照中没有匹配的 属性。例如。createdat
与value["created"]
不一样,快照中没有属性tId
类型需要匹配才能使
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
}