Swift中字典对象的Firebase实时问题
Posted
技术标签:
【中文标题】Swift中字典对象的Firebase实时问题【英文标题】:Firebase real time issue on dictionary object in Swift 【发布时间】:2019-12-26 09:23:16 【问题描述】:我正在使用 Firebase 实时获取数据。我的表结构如下。
"Bidding":
"-LwyoIpE-obs1244Zflz":
"Images":
"-LwyoIxdDbabEzKDNjz0":
"image": "bookings/15773068970yg5i.png",
"imgae_key": "-LwyoIxdDbabEzKDNjz0"
,
"-LwyoIxei2rxOOrJAxhD":
"image": "bookings/1577306897vIXfc.png",
"imgae_key": "-LwyoIxei2rxOOrJAxhD"
,
"booking_id": "1128",
"category_id": "4",
"consumer_id": "143",
"consumer_image": "/uploads/1576824430.jpeg",
"created_obj": "2019-12-25 20:48:17",
"date_time": "2019-12-26 01:47:34",
"description": "Good",
"email": "dev@consumer.com",
"job_type": "1",
"lat": "37.785834",
"lng": "-122.406417",
"order_refrence": "GATK-S-2127",
"record_id": "-LwyoIpE-obs1244Zflz",
"sub_category_id": "22",
"tile": "Contracting works - polish"
,
在视图加载时,我已成功获取“图像”数据。我调用 Firebase 节点并获取图像数据。
Database.database().reference().child("Bidding").observe(.childAdded, with: (snapshot) in
if snapshot.exists()
let values = snapshot.value as! [String: Any]
let profile = values["consumer_image"] as? String ?? ""
let images = values["Images"] as? Dictionary<String, Any>
print(messages)
)
但问题是当节点图像中添加的新子节点实时为零时。当我重新加载视图控制器图像时变得很好。请帮忙。
【问题讨论】:
您的观察者在 Bidding 节点上。这意味着当在 /Bidding/some_new_node 中直接在 Bidding 下添加新节点时,您的 firebase 观察事件将触发。但是,如果您在 Bidding/auto_id/Images 下添加子节点,该事件将不会触发,因为这不是正在观察的节点。你问的是这个吗? 是的。当新的孩子添加到 Firebase 中时,我如何观察图像节点。 添加一个新的子节点.... Bidding 节点的子节点?还是每个用户节点中 Images 节点的子节点? 【参考方案1】:由于问题仅在您从代码中添加新数据时发生(而不是在您重新加载时),我怀疑您正在添加新节点并多次调用 setValue(...)
或 updateChildValues(...)
。例如:
let newChildRef = ref.child("Bidding").childByAutoId()
newChildRef.child("booking_id").setValue("1128")
newChildRef.child("consumer_image").setValue("/uploads/1576824430.jpeg")
在上面的代码中,第一个setValue
调用将触发你的.childAdded
监听器。由于此时您还没有为consumer_image
属性写入值,因此您的侦听器中profile
的值将是nill
。
对setValue
的第二次调用会触发.childChanged
事件,而您并未在监听该事件。
您有两种解决问题的方法:
-
在一次写入操作中写入节点的所有属性。
监听节点更新。
在一次写入操作中写入节点的所有属性
为防止.childAdded
在您只为节点写入部分数据时触发,您需要确保在一次调用setValue()
或updateChildValues()
中写入所有数据。 updating specific property values 上的文档就是一个很好的例子。对于上面的代码 sn-p,这将转换为:
let values = ["booking_id": "1128",
"consumer_image": "/uploads/1576824430.jpeg"]
ref.child("Bidding").childByAutoId().setValue(values)
由于现在只有一个对 setValues
的调用,您的 .childAdded
侦听器将使用您在该(第一个/唯一)调用中传递的所有值触发。
监听节点更新
上述解决方案的替代方案是也使用.childChanged
侦听器侦听节点的更新。在这种情况下,您的侦听器将不得不处理某些属性可能还不存在。
类似:
Database.database().reference().child("Bidding").observe(.childChanged, with: (snapshot) in
let values = snapshot.value as! [String: Any]
if let profile = values["consumer_image"]
print(profile)
)
【讨论】:
实际上我想在添加新孩子时检索图像数据。我怎样才能得到那个图像节点? 在您当前的数据结构中,这意味着您需要同时监听childAdded
和 childChanged
事件。在你当前的结构中没有办法只听图像变化。以上是关于Swift中字典对象的Firebase实时问题的主要内容,如果未能解决你的问题,请参考以下文章
在 Swift 3 中包含字典的 Firebase 进程子快照