每个 tableViewCell 中的 Firebase 数据库观察者

Posted

技术标签:

【中文标题】每个 tableViewCell 中的 Firebase 数据库观察者【英文标题】:Firebase database observer in each tableViewCell 【发布时间】:2018-02-20 03:38:23 【问题描述】:

我正在创建一个聊天应用程序,其中主视图是一个 tableView,每一行代表一个聊天。该行有一个人名标签以及一个带有最新聊天消息的标签。如果用户点击一行,它将进入聊天视图。我正在使用 MessageKit 作为聊天框架。一切正常,只是我无法始终显示最近的聊天记录。

这是我的 tableView 的外观。请忽略黑色圆圈,我正在快速清除用于测试的个人照片。

我有一个使用以下方法的自定义 tableViewCell。这会从最近的消息开始为这个特定的聊天创建一个观察者。

  func getLatestChatMessage(with chatID: String) 
    guard let loggedInUserID = Auth.auth().currentUser?.uid else  return 
    DatabaseService.shared.chatsRef.child(chatID).queryLimited(toLast: 1).observe(.childAdded)  [weak self] (snapshot) in

      guard let messageDict = snapshot.value as? [String:Any] else  return 
      guard let chatText = messageDict["text"] as? String else  return 
      guard let senderId = messageDict["senderId"] as? String else  return 

      DispatchQueue.main.async 
        if senderId == loggedInUserID 
          self?.latestChatMessage.textColor = .black
         else 
          self?.latestChatMessage.textColor = UIColor(red: 0/255, green: 122/255, blue: 255/255, alpha: 1)
        
        self?.latestChatMessage.text = chatText
      
    
  

在观察到这个用户的chatID之后,我在TableView的方法cellForRowAt中调用了这个函数。

  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

    ...

     DatabaseService.shared.matchedChatIdRef.child(loggedInUserID).child(match.matchedUserId).observeSingleEvent(of: .value)  (snapshot) in
            if let chatID = snapshot.value as? String 
              cell.getLatestChatMessage(with: chatID)
            
          
      

理想情况下,这应该为每次聊天创建一个观察者,并在每次发送新消息时更新标签。我遇到的问题是它有时有效,但有时似乎停止观察。

例如,如果我在聊天 tableView 上并获得一个单元格的新消息,它会更新。但是,如果我随后点击该聊天以进入特定聊天并发送消息,然后点击后退按钮返回我的 tableView,则标签将停止更新。似乎我的观察者被移除了。有谁知道为什么我在每个牢房中的观察员停止工作?另外,如果有人建议更好地解决这个问题,我很感兴趣?我担心为每个单元格创建一个观察者可能是一个糟糕的解决方案。

编辑:我发现观察者在选择后退按钮或从下面的屏幕截图中的聊天滑回 tableView 后停止工作。

【问题讨论】:

【参考方案1】:

今天早上醒来发现我的问题...在 ChatViewController 中我调用了 removeAllObservers()

我将我的代码更新到下面,只是删除了聊天中的观察者,它解决了我的问题:

  override func viewDidDisappear(_ animated: Bool) 
    super.viewDidDisappear(true)

    if let observerHandle = observerHandle, let chatID = chatId 
      DatabaseService.shared.chatsRef.child(chatID).removeObserver(withHandle: observerHandle)
    
  

【讨论】:

以上是关于每个 tableViewCell 中的 Firebase 数据库观察者的主要内容,如果未能解决你的问题,请参考以下文章

tableviewcell中的Textview被覆盖

自定义 TableViewCell 中的标签不能是多行或换行

如何从另一种方法访问 tableviewCell 中的文本字段

如何在不创建引用插座的情况下访问静态 TableViewcells 中的文本字段?

关闭 TableViewCell 的 UIViewController

单击自定义 TableViewCell Swift 4 中的按钮时如何呈现单独的视图控制器?