我正在为项目添加评论,一切似乎都在运行,但是我的桌面视图显示评论并没有得到正确更新,直到我离开屏幕然后再返回。
一旦输入评论并且"发送"按下,评论以及评论作者将发布到Firebase。然后将包含这两个值的字典循环并将注释放入一个数组中,同时注释作者进入另一个数组(这样我就可以使用数组' indexPaths填充我的表视图):
@IBAction func addCommentButtonPressed(_ sender: Any) {
if addCommentTextField.text != nil {
if let comment = addCommentTextField.text {
print(comment)
let ref = FIRDatabase.database().reference()
let keyToPost = ref.child("posts").childByAutoId().key
ref.child("posts").child(self.postID).observeSingleEvent(of: .value, with: { (snapshot) in
if let post = snapshot.value as? [String : AnyObject] {
let updateComments: [String: Any] = ["comments/\(FIRAuth.auth()!.currentUser!.displayName!)" : comment]
ref.child("posts").child(self.postID).updateChildValues(updateComments, withCompletionBlock: { (error, reff) in
if error == nil {
ref.child("posts").child(self.postID).observeSingleEvent(of: .value, with: { (snap) in
if let properties = snap.value as? [String: AnyObject] {
if let commentLoop = post["comments"] as? [String : AnyObject] {
for (person, comment) in commentLoop {
self.selectedPost.commentAuthors.append(person)
self.selectedPost.commentText.append(comment as! String)
}
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
})
}
})
}
})
ref.removeAllObservers()
}
}
addCommentTextField.resignFirstResponder()
self.addCommentTextField.text = nil
self.view.endEditing(true)
self.addCommentView.isHidden = true
}
这就是我的Firebase数据库的样子:
我不确定问题是什么。我觉得我在正确的地方打电话给self.tableView.reloadData()
。这是我的获取功能(在显示图片的FeedViewController
中,而不是通过点击{{1}中的一个图片来获得评论PhotoDetailController
的{{1}} }}):
PhotoDetailController
在发布评论后重新加载tableView会出现问题,还是在fetch函数中?就像我说的一切似乎都与firebase一起正常工作一样,我就像tableView一样,它会更新评论,以便在发布后立即显示评论。
编辑:感谢Jen的精彩建议..我尝试了一些小改动,以摆脱警告/错误:
FeedViewController
这些是我的tableView方法:
func fetchPosts() {
let ref = FIRDatabase.database().reference()
ref.child("users").queryOrderedByKey().observe(.value, with: { snapshot in
let users = snapshot.value as! [String : AnyObject]
for (_, value) in users {
// get uid as string
if let uid = value["uid"] as? String {
// check to make sure uids match
if uid == FIRAuth.auth()?.currentUser?.uid {
// check for followers
if let followingUsers = value["following"] as? [String : String] {
// loop through those and add them to "following" array
for (_, user) in followingUsers {
self.following.append(user)
}
}
// add current user to that array also so you can see your own posts
self.following.append(FIRAuth.auth()!.currentUser!.uid)
ref.child("posts").queryOrderedByKey().observeSingleEvent(of: .value, with: { (snap) in
let postsSnap = snap.value as! [String : AnyObject]
for (_, post) in postsSnap {
if let userID = post["userID"] as? String {
for each in self.following {
if each == userID {
// here are the posts that the user should see (his own and his following)
let posst = Post()
if let author = post["author"] as? String, let likes = post["likes"] as? Int, let pathToImage = post["pathToImage"] as? String, let postID = post["postID"] as? String {
posst.author = author
posst.likes = likes
posst.pathToImage = pathToImage
posst.postID = postID
posst.userID = userID
if let people = post["peopleWhoLike"] as? [String : AnyObject] {
for (_, person) in people {
posst.peopleWhoLike.append(person as! String)
}
}
if let commentLoop = post["comments"] as? [String : AnyObject] {
for (person, comment) in commentLoop {
posst.commentAuthors.append(person)
posst.commentText.append(comment as! String)
}
}
posts.append(posst)
}
}
}
self.collectionView.reloadData()
}
}
})
ref.removeAllObservers()
}
}
}
})
}
答案 0 :(得分:3)
看起来fetchPosts
都会更新数据库并侦听更改。我建议您设置仅更新数据库的功能。然后有一个单独的函数在视图中调用一次,并使用.observe(.childAdded)
在tableView出现在数据库中时将新注释附加到tableView。
编辑: 由于您不熟悉Firebase,因此以下是一些简化代码和更新tableView的具体建议:
在"帖子"之外创建一个单独的孩子。举行评论。有时您可能希望从不包含评论的帖子中访问某些信息,因此最好通过保持数据库保持平稳来最小化您下载的额外数据量。使用相同的postId链接帖子和帖子评论。
结果看起来像这样:
"posts":
"-postIdKey":
"photoPath": "..."
"name": "..."
"date": "..."
"...": "..."
"postComments:"
"-postIdKey":
"-commentIdPush1":
"userId": "uId1"
"comment": "Love this pic!"
"-commentIdPush2":
"userId": "uId2"
"comment": "Wow!"
在addCommentButtonPressed
中,如果文本字段中有文本,请调用addComment,将文本作为参数传递。创建一个字典来保存您将传递给setValue的数据。一旦您设置了密钥的值,就可以使用#Id; userId"和"评论",使用childByAutoId为postCommentsRef创建一个新子项并传递评论数据。
@IBAction func addCommentButtonPressed(_ sender: Any) {
if !addCommentTextField.text!.isEmpty {
addComment(addCommentTextField.text!)
}
}
func addComment(comment: String) {
var commentData: [String: String] = [:]
commentData["userId"] = self.userID
commentData["comment"] = comment
postCommentsRef.childByAutoId().setValue(commentData)
}
不是观察.value
的单个事件,而是通过创建观察新评论的侦听器来利用Firebase数据库的实时性。您可以创建另一个在此之后建模的功能来收听新帖子。
let postsCommentsRef = FIRDatabase.database().reference().child("postComments").child(postID)
func observePostComments() {
postsCommentsRef.observe(.childAdded, with: { snapshot in
let comment = snapshot.value as! [String: String]
self.comments.append(comment["userId"])
self.commentAuthors.append(comment["comment"])
self.yourTableView.insertRows(at: [IndexPath(row: self.comments.count-1, section: 0)], with: .automatic)
})
}
注意#2和#3中关注点的分离。 addCommentButtonPressed
仅关注向数据库添加新注释。 observePostComments
仅关注从数据库向UITableView
添加新评论。