【问题标题】:Chat conversation for firebase in swift快速的firebase聊天对话
【发布时间】:2018-06-04 16:17:56
【问题描述】:

我使用了这个模型:

import Foundation
class Chat {
var message: String?
var senderID: String
var receiverID: String
var timestamp : String

init(messageTextString: String?, senderIDNumber: String, receiverIDNumber: String, timeStampString: String){
    message = messageTextString
    senderID = senderIDNumber
    receiverID = receiverIDNumber
    timestamp = timeStampString
}
}

对于 ChatViewController:

func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int{
    return chats.count
}

  func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell{
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! ChatCollectionViewCell    
     let senderIDNumber = Auth.auth().currentUser?.uid
        if chats[indexPath.row].senderID == senderIDNumber {
        if let chatsText = chats[indexPath.row].message{
            let size = CGSize(width: 250, height: 1000)
            let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
            let estimatedFrame = NSString(string: chatsText).boundingRect(with: size, options: options, attributes: [NSAttributedStringKey.font : UIFont.systemFont(ofSize: 18)], context: nil)
            cell.messageSend.frame = CGRect(x:8,y:0,width:estimatedFrame.width + 16, height:estimatedFrame.height + 20)
            cell.textBubbleView.frame = CGRect(x:0,y:0,width:estimatedFrame.width + 16 + 8, height:estimatedFrame.height + 20)
         //showOutgoingMessage(text: chats[indexPath.row].message)
    }
            cell.messageSend.text = chats[indexPath.row].message
    }
    else {
          /*cell.messageReceived.text = chats[indexPath.row].message */
            let chatsText = chats[indexPath.row].message
            let size = CGSize(width: 250, height: 1000)
            let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
            let estimatedFrame = NSString(string: chatsText!).boundingRect(with: size, options: options, attributes: [NSAttributedStringKey.font : UIFont.systemFont(ofSize: 18)], context: nil)
            cell.messageSend.frame = CGRect(x:view.frame.width - estimatedFrame.width,y:0,width:estimatedFrame.width + 16, height:estimatedFrame.height + 20)
            cell.textBubbleView.frame = CGRect(x:view.frame.width - estimatedFrame.width,y:0,width:estimatedFrame.width + 16 + 8, height:estimatedFrame.height + 20)
    }
    return cell
 }

@objc func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
if let chatsText = chats[indexPath.row].message {
    let size = CGSize(width: 250, height: 1000)
        let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
        let estimatedFrame = NSString(string: chatsText).boundingRect(with: size, options: options, attributes: [NSAttributedStringKey.font : UIFont.systemFont(ofSize: 18)], context: nil)
        return CGSize(width: view.frame.width, height: estimatedFrame.height + 20)
    }
    return CGSize(width: view.frame.width, height: 200)
}

func loadPosts() {
    let ref = Database.database().reference()
    let senderIDNumber = Auth.auth().currentUser?.uid
    ref.child("chats").queryOrdered(byChild: "senderID").queryEqual(toValue: senderIDNumber).observe(.childAdded) { (snapshot: DataSnapshot) in
        if  let dict = snapshot.value as? [String: Any] {
            let messageText = dict["message"] as! String
            let senderIDNumber = dict["senderID"] as! String
            let receiverIDNumber = dict["receiverID"] as? String
            let timestamp = dict["timestamp"] as? String
            let chat = Chat(messageTextString: messageText, senderIDNumber: senderIDNumber, receiverIDNumber: receiverIDNumber!, timeStampString: timestamp!)
            //append(post) to array
            self.chats.append(chat)
            print(self.chats)
           self.collectionView.reloadData()
        }
    }
}

 func loadPostsReceivedMessage() {
    let ref = Database.database().reference()
    ref.child("chats").queryOrdered(byChild: "receiverID").queryEqual(toValue: receiverIDNumber).observe(.childAdded) { (snapshot: DataSnapshot) in
        if  let dict = snapshot.value as? [String: Any] {
            let messageText = dict["message"] as! String
            let senderIDNumber = dict["senderID"] as! String
            let receiverIDNumber = dict["receiverID"] as? String
            let timestamp = dict["timestamp"] as? String
            let chat = Chat(messageTextString: messageText, senderIDNumber: senderIDNumber, receiverIDNumber: receiverIDNumber!, timeStampString: timestamp!)
            self.chats.append(chat)
            print(self.chats)
            self.collectionView.reloadData()
        }
    }
}

}

我希望能够区分传出和传入消息,但无法做到。我确实想过创建一个 inComing 布尔值来区分传出和传入消息;但不知道如何实施。 我需要帮助和建议,非常感谢

【问题讨论】:

    标签: ios swift firebase firebase-realtime-database


    【解决方案1】:

    Firebase 无法查询!!!(尤其是多重排序)..需要迁移到 firestorm(firebase 存储的新 Beta 版)或使用 angular。

    【讨论】:

      【解决方案2】:

      能够区分发送的消息和接收的消息就像向 Chat 对象添加属性一样简单,因此您可能会遇到这样的事情:

      class Chat {
          var message: String
          var senderID: String
          var receiverID: String
          var timestamp : String
          var isFromCurrentUser: Bool = false // You'll only need to change this property if the message is from the current sender.
      
          init(messageTextString: String?, senderIDNumber: String, receiverIDNumber: String, timeStampString: String){
              self.message = messageTextString
              self.senderID = senderIDNumber
              self.receiverID = receiverIDNumber
              self.timestamp = timeStampString
          }
      }
      

      修改对象后,您需要查看获取数据的方式。我建议将 loadPosts() 重命名为 listenForChatItemAdded() 并将函数更改为以下内容:

      注意:不需要使用查询。当您只有某组数据时,查询特别有用;在这里,您最好抓取数据,并在对象初始化后对其进行排序。

      func loadPosts() {
          let ref = Database.database().reference()
          let senderIDNumber = Auth.auth().currentUser?.uid
          ref.child("chats").observe(.childAdded) { (snapshot: DataSnapshot) in
              if  let dict = snapshot.value as? [String: Any] {
                  let messageText = dict["message"] as! String
                  let senderIDNumber = dict["senderID"] as! String
                  let receiverIDNumber = dict["receiverID"] as? String
                  let timestamp = dict["timestamp"] as? String
      
                  let chat = Chat(messageTextString: messageText, senderIDNumber: senderIDNumber, receiverIDNumber: receiverIDNumber!, timeStampString: timestamp!)
      
                  let currentUserUID = Auth().auth().currentUser!.uid
                  if senderID == currentUserUID {
                      chat.isFromCurrentUser = true
                  }
      
                  //append(post) to array
                  self.chats.append(chat)
      
                  //after adding the new chat tot the array, sort the array
                  let sorted = filtered.sorted { (chat1, chat2) -> Bool in
                      return chat1.timestamp > chat2.timestamp
                  }
      
                  // update the current array with the sorted array
                  self.chats = sorted
      
                  // reload the collectionView
                  self.collectionView.reloadData()
              }
          }
      }
      

      最后,只需检查我们创建的属性以确定您应该如何直观地设置单元格。我将创建 UICollectionViewCell 的两个子类。一个用于发送者,一个用于接收者。如果聊天是由当前用户发送的,则使用 sender 子类创建一个单元格,如果聊天是由其他人发送的,则使用 receiver 子类。

      希望这会有所帮助, 干杯!

      【讨论】:

      • 几天前我设法解决了它,但我遇到了另一个问题。因为我想创建一个收件箱。我无法按照收件箱的外观分开对话。
      猜你喜欢
      • 2013-07-11
      • 1970-01-01
      • 1970-01-01
      • 2011-05-18
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多