当/media 节点上的数据更新时,我正在尝试从 media
读取数据,但未调用 .observe(.childAdded
。
例如,我在 /media/-LKN1j_FLQuOvnhEFfao/caption
更新数据,但我从未在 observeNewMedia 中收到事件。
当 ViewDidLoad
完成时,我第一次可以毫无问题地读取数据。
第一步是下载用户数据,第二步是从 currentUser 获取位置,最后一步是在媒体上附加一个监听器 .childAdded
。< br/>
我怀疑该事件没有被触发,因为在 DDatabaseRReference.users(uid: uid).reference().observe(.value
fetchMedia
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
最佳答案
让我们首先更新结构,使其更具可查询性
假设一个用户节点
users
-Q6Dm3IMLNLgBH3ny3rv2CMYf47p1 //this is each users uid
email: "john@gmail.com"
locality: "barking"
和一个包含所有用户媒体的媒体节点
media
-abcdefg12345 //node created with childByAutoId
caption: "santa"
for_uid: -Q6Dm3IMLNLgBH3ny3rv2CMYf47p1 //matches the uid in the /users node
然后是我们的主视图 Controller ,它包含对 Firebase 的引用并记录用户
class ViewController: UIViewController {
var ref: DatabaseReference!
override func viewDidLoad() {
super.viewDidLoad()
self.ref = Database.database().reference()
//log user in which will populate the Auth.auth.currentUser variable
}
.
.
.
我们需要一个对象来存储媒体,然后需要一个数组来保存这些对象
class MediaClass {
var key = ""
var caption = ""
init(k: String, c: String) {
self.key = k
self.caption = c
}
}
var mediaArray = [MediaClass]()
然后设置观察者,当该用户的媒体被添加、更改或删除时,观察者将添加、更新或从数组中删除。
let thisUid = Auth.auth().currentUser?.uid
let mediaRef = self.ref.child("media")
let queryRef = mediaRef.queryOrdered(byChild: "for_uid").queryEqual(toValue: thisUid)
queryRef.observe(.childAdded, with: { snapshot in
let dict = snapshot.value as! [String: Any]
let key = snapshot.key
let caption = dict["caption"] as! String
let m = MediaClass.init(k: key, c: caption)
self.mediaArray.append(m)
self.tableView.reloadData()
})
queryRef.observe(.childChanged, with: { snapshot in
let dict = snapshot.value as! [String: Any]
let key = snapshot.key
let caption = dict["caption"] as! String
let index = self.mediaArray.index { $0.key == key } //locate this object in the array
self.mediaArray[index!].caption = caption //and update it's caption
self.tableView.reloadData()
})
//leaving this an an exercise
queryRef.observe(.childRemoved....
请注意,我们通过查询向媒体节点添加了 .childAdded、.childChanged 和 .childRemoved 事件,因此应用将收到的唯一事件是与该用户相关的事件。
另请注意,没有错误检查,因此需要添加。
关于swift - 为什么添加新数据时不调用 .childAdded?火力地堡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51934893/