【发布时间】:2018-08-20 16:22:54
【问题描述】:
当数据在 /media 节点上更新时,我试图从 media 读取数据,但未调用 .observe(.childAdded。
例如,我在 /media/-LKN1j_FLQuOvnhEFfao/caption 更新数据,但我从未在 observeNewMedia 中收到事件。
当ViewDidLoad 完成时,我第一次可以毫无问题地读取数据。
第一步是下载用户数据,第二步是从 currentUser 获取locality,最后一步是在媒体上附加一个监听器.childAdded。
我怀疑该事件没有被触发,因为fetchMedia 在DDatabaseRReference.users(uid: uid).reference().observe(.value 内部被调用
media
-LKNRdP4ZsE3YrgaLB30
caption: "santa"
mediaUID: "-LKNRdP4ZsE3YrgaLB30"
locality: "barking"
users
Q6Dm3IMLNLgBH3ny3rv2CMYf47p1
media
-LKNReJCxgwtGRU6iJmV: "-LKNRdP4ZsE3YrgaLB30"
email: "john@gmail.com"
locality: "barking"
//enables the programmer to create references to different childs in Firebase
enum DDatabaseRReference {
case root
case users(uid:String)
case media //to store photos
func reference() -> DatabaseReference {
return rootRef.child(path)
}
//return root reference to our database
private var rootRef: DatabaseReference {
return Database.database().reference()
}
private var path: String {
switch self { //self is the enum DDatabaseReference
case .root:
return ""
case .users(let uid):
return "users/\(uid)"
case .media:
return "media"
}
}
}//end of enum DatabaseReference
class NewsfeedTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
//observe ~/users/uid
DDatabaseRReference.users(uid: uid).reference().observe(.value, with: { (snapshot) in
DispatchQueue.main.async {
if let userDict = snapshot.value as? [String : Any] {
self.currentUser = UserModel(dictionary: userDict)
self.fetchMedia()
self.tableView.reloadData()
}
}
})
}
func fetchMedia() {
Media.observeNewMedia((currentUser?.locality)!) { (newMedia) in
//check if newly downloaded media is already in media array
if !self.media.contains(newMedia) {
self.media.insert(newMedia, at: 0)
self.tableView.reloadData()
}else {
//remove old media and add the newly updated one
guard let index = self.media.index(of: newMedia) else {return}
self.media.remove(at: index)
self.media.insert(newMedia, at: 0)
self.tableView.reloadData()
}
}
}
}//end of NewsfeedTableViewController
class Media {
class func observeNewMedia(_ userLocality: String, _ completion: @escaping (Media) -> Void) {
DDatabaseRReference.media.reference().queryOrdered(byChild: "locality").queryEqual(toValue: userLocality).observe(.childAdded, with: { snapshot in
guard snapshot.exists() else {
print("no snap ")
return}
print("snap is \(snapshot)")
let media = Media(dictionary: snapshot.value as! [String : Any])
completion(media)
})
}
} //end of class Media
【问题讨论】:
-
您正在通过子“位置”观察一个节点,该节点似乎不存在于问题中包含的 Firebase 结构中。目前尚不清楚实际上正在观察/查询哪个节点。问题说您正在尝试观察媒体节点,但您添加了一个查询来“过滤”结果,而不仅仅是一个观察者。此外,您正在使用 media.reference() 但不清楚原因。
-
@Jay 我创建了一个枚举
DDatabaseRReference以便更轻松地创建对 firebase 的引用。在 viewDidLoadusers/userUID中观察到。初始化 UserModel 并且我拥有locality属性的值后,将对media/mediaUID进行查询,同时将childAdded事件附加到 firebase 引用。我想要的是每次在/media/mediaUID添加或修改孩子或其后代孩子时从 firebase 获取更新。换句话说,如果media/-LKNRdP4ZsE3YrgaLB30/caption接收到一个新值,我想接收那个数据。 -
mediaUID 在 Firebase 结构中没有这样的子级。它显示 mediaUID: "-LKNRdP4ZsE3YrgaLB30" 所以它的孩子是 -LKNRdP4ZsE3YrgaLB30 的字符串。我认为您可能希望 .observe 使用 .childAdded 到媒体节点以在将孩子添加到该节点时获取事件。此外,没有理由存储与父节点具有相同值的子节点,因为 parentNode 是键,它始终可从 snapshot.key 获得。
-
问题中有相当多的代码,因此不清楚您要做什么。这是一个猜测——让我知道这是否准确;对于当前登录的用户,您希望在从媒体节点添加、更改或删除新媒体时接收事件?然后这些更改应反映在 self.media 数组中,以便 UI 可以相应更新
-
是的,这正是我想要的。对于当前登录的用户,我想在添加、更改或删除新媒体时接收事件: media/mediaUID 。 mediaUID 是我用来识别每个媒体对象的值。您可以看到该值在 /users LKNRdP4ZsE3YrgaLB30 中出现一次,然后在 /media 中再次出现。
标签: swift firebase firebase-realtime-database