【问题标题】:Reading Firebase child by auto ID swift通过自动 ID swift 读取 Firebase 孩子
【发布时间】:2018-06-12 06:44:51
【问题描述】:

这是我的 Firebase 树的快速输出,id 喜欢访问 people_on_this_planit / userID 节点。我唯一的问题是该节点在自动 ID 内;请任何帮助将不胜感激。谢谢

  planits
 -LEmgxuG_13KNA5inRaB
     Planit Title: "Some title"
     people_on_planit
      -LEmh6IxqguVBJEwghZv (auto ID)
         userID: "kkdiEW0D9"
     senderId: "39FdLfdIO8832"

现在我使用的代码如下,但是当我打印 peopleonplanit 时我得到了 nil。

ref = Database.database().reference()
let userID = Auth.auth().currentUser?.uid       
let planitsRef = ref.child("planits")

for child in snapshot.children {

    let childSnap = child as! DataSnapshot
    let dict = childSnap.value as! NSDictionary
    let planKey = childSnap.key
    //print(planKey)

    print(dict)


    let title = dict["Planit Title"] as! String
    let senderID = dict["senderId"] as! String
    let peopleOnPlanit = dict["people_on_planit"] as? String

    print(peopleOnPlanit)
}

【问题讨论】:

  • 好的。回答一个问题:你认为键 "people_on_planit" 中的 valueString 吗? 它又是一本字典。并且不要在swift中使用NS前缀类型
  • 哦,是的,哇,我知道我的错误在哪里了。我将其视为字符串而不是字典。哇。谢谢
  • swift 让我在这里使用 NSDictionary。使用普通字典我得到一个错误
  • 你用什么代替了NSDictionary
  • 我试着只放字典

标签: swift firebase


【解决方案1】:

这是阅读问题中提出的 Firebase 结构的代码

let planitsRef = self.ref.child("planits")
planitsRef.observeSingleEvent(of: .value, with: { snapshot in

    for child in snapshot.children {
        let planSnap = child as! DataSnapshot
        let planDict = planSnap.value as! [String: Any]
        let title = planDict["plan_title"] as! String
        let senderId = planDict["sender_id"] as! String
        print("plan title: \(title)  senderId: \(senderId)")
        let peopleOnPlanitSnap = planSnap.childSnapshot(forPath: "people_on_planit")

        for peopleChild in peopleOnPlanitSnap.children {
            let peopleChildSnap = peopleChild as! DataSnapshot
            let userSnapDict = peopleChildSnap.value as! [String: Any]
            let userId = userSnapDict["user_id"] as! String
            print("  userId: \(userId)")
        }
    }
})

和输出

plan title: Some title  senderId: 39FdLfdIO8832
  userId: uid_0
  userId: uid_1

-- 一些笔记--

由于关联的用户似乎是由他们的用户 ID 存储的,并且这是该节点中存储的唯一数据,因此您可能需要更改该节点

people_on_planit
      -LEmh6IxqguVBJEwghZv (auto ID)
         userID: "kkdiEW0D9"

看起来像这样

people_on_planit
   uid_x: true //uid_x would be kkdiEW0D9 etc
   uid_y: true

它更浅更干净,并且需要更少的代码来阅读它。此外,如果出现这种情况,您可以更轻松地查询它。

还请注意,我稍微更改了命名约定;欢迎您随意格式化密钥,但我使用 plan_title 之类的密钥,而不是 PlanIt Titlesender_iduser_id em> 而不是 senderId 和 userId。我的做法是对于实际的 firebase 键,我使用全部小写、下划线而不是空格,并且在代码中,我使用小写/大写且没有空格。因此,如果您复制粘贴我的代码,则需要更改这些代码。

【讨论】:

  • 感谢@jay,这是正确的解决方案。我可以看到我的不匹配现在在哪里。至于你留下的笔记 - 我绝对同意你的假设,我需要查询它以经常删除或修改节点。那么这只是一个布尔而不是自动ID的孩子吗?这就是“uid_x:true”存在的原因吗?也感谢您的洞察力,非常感谢。
  • @CodingwhileLoading 很高兴它有帮助!重构 people_on_planit 节点非常酷,因为您知道路径,无需查询即可获取数据; bool true 充当占位符。例如,您想查看 uid_y 是否在 people_on_planit 节点中,您可以在 /planit_node/people_on_planit/uid_y 上观察SingleEvent,如果 snapshot.exists == true,则该 uid 在该节点中。此外,如果您想获取用户列表,您可以读取 people_on_planit 节点并遍历子节点,获取每个键(uid),然后可以使用它来查找每个用户。
  • 哦,太好了!这将为我省去很多未来的麻烦。我将重组我的 Firebase 以匹配它。这就是我将数据推送到 Firebase 的方式 - 所以我可以用布尔值代替最后的字典吗?或者我错过了一两步 _REF_PLANITS.child(withKeyOfPlanit).child("people_on_planit").childByAutoId().updateChildValues(["user" : userKey])
  • 当我说 bool 时,我的意思是 ([userKey: true]) - 用户密钥是那个人的 UID
  • @CodingwhileLoading 在这种情况下,不要在 people_on_planit 节点上使用 childByAutoId。它非常适合创建父子节点以帮助将子数据与其父节点分离,但这里的选择是错误的。这样做 _REF_PLANITS.child(withKeyOfPlanit).child("people_on_planit").child(uid).setValue(true) 如果你想删除它 _REF_PLANITS.child(withKeyOfPlanit).child ("people_on_planit").child(uid).removeValue() 其中 uid 是您要从该节点添加或删除的用户 uid。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多