点击时更新 tableView 单元格中的 Firebase 数据

Posted

技术标签:

【中文标题】点击时更新 tableView 单元格中的 Firebase 数据【英文标题】:Update Firebase data in tableView cell on tap 【发布时间】:2017-02-12 13:14:37 【问题描述】:

我正在使用 Firebase 实时数据库在 tableView 中显示帖子。当用户双击相应的单元格时,我想增加特定帖子的点赞数。

我的双击工作正常,并且已经打印出正确的indexPath

override func viewDidLoad() 
  super.viewDidLoad()
  // double tap
  let doubleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleDoubleTap(sender:)))
  doubleTapGestureRecognizer.numberOfTapsRequired = 2
  postTableView.addGestureRecognizer(doubleTapGestureRecognizer)

这是我根据 Firebase 文档尝试更新喜欢的内容:

func handleDoubleTap(sender: UITapGestureRecognizer) 
  let touchPoint = sender.location(in: postTableView)
  if let indexPath = postTableView.indexPathForRow(at: touchPoint) 
    print(indexPath)
    let post = posts[indexPath.row]
    let oldLikes = post.likes
    let newLikes = oldLikes! + 1
    let postUpdates = ["\(post.likes)": newLikes]
    database.updateChildValues(postUpdates)
    postTableView.reloadData()
  

它不会抛出任何错误但不工作。

这是数据库结构:

这是我声明数据库的方式:

struct post 
  let author : String!
  let creationDateTime : String!
  let content : String!
  let likes : Int!

viewDidLoad

let database = FIRDatabase.database().reference()

这就是我创建帖子的方式:

@IBAction func savePost(_ segue:UIStoryboardSegue) 
    let addPostVC = segue.source as! AddPostViewController
    let author = currentUser.displayName
    let date = Date()
    let formatter = DateFormatter()
    formatter.dateFormat = "dd.MM.yyyy"
    let dateResult = formatter.string(from: date)
    let creationDateTime = "\(dateResult)"
    let content = addPostVC.passTextContent
    let likes = 0
    let post : [String : AnyObject] = ["author" : author as AnyObject,
                                       "content" : content as AnyObject,
                                       "creationDateTime" : creationDateTime as AnyObject,
                                       "likes" : likes as AnyObject]
    database.child("Posts").childByAutoId().setValue(post)

这就是我在viewDidLoad中检索数据的方式

database.child("Posts").queryOrderedByKey().observe(.childAdded, with: 
  snapshot in
  let postID = (snapshot.value as? NSDictionary)?["postID"] as? String ?? ""
  let author = (snapshot.value as? NSDictionary)?["author"] as? String ?? ""
  let content = (snapshot.value as? NSDictionary)?["content"] as? String ?? ""
  let creationDateTime = (snapshot.value as? NSDictionary)?["creationDateTime"] as? String ?? ""
  let likes = (snapshot.value as? NSDictionary)?["likes"] as? Int ?? 0
  self.posts.insert(post(postID: postID, author: author, creationDateTime: creationDateTime, content: content, likes: likes), at: 0)
  self.postTableView.reloadData()
)

【问题讨论】:

双击后,post.likes 的 firebase 数据库中是否有任何更新? 不,什么都没有发生 好的,你能展示你的数据库结构吗?你如何声明变量database?我的意思是,请将其添加到您的问题中 当然,做到了。 【参考方案1】:

您的数据库引用有问题。当您执行let database = FIRDatabase.database().reference() 时,您指的是数据库结构中的主节点。这意味着您将使用数据库 Json 中根目录下的结构。它唯一的孩子将是Posts 键。

当你这样做时

let postUpdates = ["\(post.likes)": newLikes]
database.updateChildValues(postUpdates)

您正在尝试更新根节点下的值,该值显然不存在。它可以找到的唯一参考是密钥Posts

为了在正确的位置执行更新,您可以从主要参考中获取子参考,尤其是您有兴趣更新的帖子的参考。

例如,您可以执行以下操作:

let postReference = database.child("Here goes the post Id").

然后,您将能够在此新引用上正确使用updateChildValues,因为它将更新特定帖子。

另一个可能被错误使用的东西是被发送到updateChildValues 的字典。您必须提供的字典结构如下:

["key that you want to update": new value]

因此,在您的情况下,您应该提供如下字典,而不是提供以前的点赞数和新的点赞数:

let postUpdates = ["likes": newLikes]

【讨论】:

好的,谢谢,这是有道理的,但是我如何获得所选单元格的postID 不客气!好吧,我想您正在从 firebase 数据库中获取您在 tableView 中显示的帖子,不是吗?然后,您还应该将 firebase 返回的对象中的 Id 保存到您的 post 结构中。我在您的代码中看不到您是如何创建/检索帖子的 我添加了创建和检索数据的方式 - 现在我正在努力将 autoID 添加到 post 您遇到了什么问题?无法访问id? 好的,终于明白了!感谢您的帮助!

以上是关于点击时更新 tableView 单元格中的 Firebase 数据的主要内容,如果未能解决你的问题,请参考以下文章

如何更新 TableView 静态单元格中的数据?

当点击自定义 TableView 单元格中的 UITextField 时转到新视图

TableView 交互阻止单元格中的动画

重用 tableview 单元格中的元素

只有在 iOS 7 中点击单元格时,tableview 单元格中的 labeltext 才会消失

在 tableview 单元格中显示图像