gpt4 book ai didi

swift - 为什么添加新数据时不调用 .childAdded?火力地堡

转载 作者:行者123 更新时间:2023-11-28 14:21:02 27 4
gpt4 key购买 nike

当/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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com