2017-05-21 3 views
0

사용자가 대화를 할 때 대화를 tableViewController에 표시하고자합니다. 예를 들어, User1이 User2에 10 개의 메시지를 보내는 경우 User1 - User2 대화에서 보낸 마지막 메시지를 표시하는 TableView에 하나의 셀이 있어야합니다. User1이 User3에 4 개의 메시지를 보내면 User1은 두 개의 tableView 셀을 가져야하고 User2와 User3은 하나의 메시지 만 가져야합니다. 내 데이터베이스는 다음과 같습니다firebase에서 사용자 메시지 가져 오기

나는 모든 메시지를 검색하고 messagesViewController에서 그들을 볼 수 아래의 기능을 사용하고
messages 
     hx1DXeMFRU 
     -KkVUFuhv7xsYVhnjldV 
       ReceiverId: "hx1DX1hW5JZMSmDjwQRUYo3i5Yt2" 
       senderId: "eMFRUhfmckTq9cRWNnwIc9mqxxv1" 
       text:"hey" 
       convoId: hx1DXeMFRU 
       timestamp: 1495193736.860723 
      -KkVUJG8VPOijCvzMKRf 
       ReceiverId: "eMFRUhfmckTq9cRWNnwIc9mqxxv1" 
       senderId: "hx1DX1hW5JZMSmDjwQRUYo3i5Yt2" 
       text:"Hey how are you?" 
       convoId: hx1DXeMFRU 
       timestamp: 1495193699.448048 

. 그러나 두 명의 고유 한 사용자간에 대화를 추가하려고하면 모든 메시지가 하나의 셀에 추가됩니다. 따라서 구체적인 예제에서 User1과 User2, User1이 User3과 통신하는 두 개의 셀이 있어야합니다.

import UIKit 
import Firebase 
import FirebaseStorage 
import FirebaseAuth 
import FBSDKCoreKit 
import FBSDKLoginKit 
import FirebaseDatabase 
import JSQMessagesViewController 


class MessagesTableViewController: UITableViewController { 

    var databaseRef = FIRDatabase.database().reference() 
    var loggedInUser = FIRAuth.auth()?.currentUser 
    var loggedInUserUid = FIRAuth.auth()?.currentUser?.uid 
    var dictDetails: [String:AnyObject]? 
    var messages = NSMutableArray() 
    var messagesArray = [String]() 
    var convoId: String? 
    var receiverData: AnyObject? 
    let storage = FIRStorage.storage() 

    var senderId = FIRAuth.auth()?.currentUser?.uid 

    @IBOutlet var MessageTableView: UITableView! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     self.navigationController?.navigationBar.barTintColor = UIColor(red:0.23, green:0.73, blue:1.00, alpha:1.0) 
     self.navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.white] 

     self.navigationItem.title = "Messages" 
     self.navigationItem.rightBarButtonItem?.tintColor = UIColor.white 
     self.navigationItem.leftBarButtonItem?.tintColor = UIColor.white 


     loadData() 

    } 


    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 


    func loadData() 
    { 
     let uidToFind = loggedInUserUid as String! 
     FIRDatabase.database().reference().child("messages") 
      .queryOrdered(byChild: "ReceiverId") 
      .queryEqual(toValue: uidToFind).queryLimited(toLast: 1) 
      .observe(.childAdded, with: { snapshot in 

       let msgDict = snapshot.value as! [String: Any] 
       let msg = msgDict["ReceiverId"] as! String 
       self.messages = [] 
       self.messages.append(msg) 
       self.MessageTableView.reloadData() 
      }) 
    } 

     // MARK: - Table view data source 

    override func numberOfSections(in tableView: UITableView) -> Int { 
     // #warning Incomplete implementation, return the number of sections 
     return 1 
    } 

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     if messages.count > 0 { 
      tableView.backgroundView = .none; 
      tableView.separatorStyle = .singleLine 
      return self.messages.count 
     } 
     else{ 
      let noDataLabel: UILabel  = UILabel(frame: CGRect(x: 0, y: 0, width: tableView.bounds.size.width, height: tableView.bounds.size.height)) 
      noDataLabel.text   = "No Messages" 
      noDataLabel.textColor  = UIColor.lightGray 
      noDataLabel.textAlignment = .center 
      tableView.backgroundView = noDataLabel 
      tableView.separatorStyle = .none 
      return 0 
     } 
    } 
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "MessageCell", for: indexPath) as! MessageTableViewCell 


     //Configure the cell 


     print(messages[indexPath.row]) 
     let message = self.messages[indexPath.row] as! [String: AnyObject] 
     if let seconds = message["timestamp"] as? Double { 
      let timeStampDate = NSDate(timeIntervalSince1970: seconds) 
      let dateFormatter = DateFormatter() 
      dateFormatter.dateFormat = "hh:mm a" 
      cell.Time.text = dateFormatter.string(from: timeStampDate as Date) 
     } 



     cell.Message.text = message["text"] as? String 


     if let imageName = message["ReceiverId"] as? String { 

      let ref = FIRDatabase.database().reference().child("posts").child(imageName) 

     ref.observeSingleEvent(of: .value, with: { (snapshot) 
      in 

      if let dictionary = snapshot.value as? [String: AnyObject]{ 
       for post in dictionary { 
        let messages = post.value as! [String: AnyObject] 
        for (id, value) in messages { 

        cell.SellerName.text = messages["username"] as? String 
         if (messages["uid"] as? String) != nil { 
          let uidPoster = messages["uid"] as? String 
          let imageRef = FIRStorage.storage().reference().child((uidPoster)!+"/profile_pic.jpg") 

          imageRef.data(withMaxSize: 25 * 1024 * 1024, completion: { (data, error) -> Void in 
           if error == nil { 

            let image = UIImage(data: data!) 
            cell.UserPic.image = image 

            cell.UserPic.layer.cornerRadius = 30 
            cell.UserPic.clipsToBounds = true 



           }else { 

           }})} 
              self.messages.add(value) 
        }}}})} 

     return cell 
    } 
} 
+0

같은

뭔가 텍스트가 아닌 이미지와 같은 중포 기지 구조 문제를 업데이트하십시오. 이미지를 검색 할 수 없으며 대답에 사용해야하는 경우 다시 입력해야합니다. Firebase 콘솔 -> 오른쪽 3 점> JSON 내보내기를 통해 구조를 가져올 수 있습니다. – Jay

+0

두 명의 고유 한 사용자 *간에 대화를 추가하려고 시도하는 것이 분명하지 않습니다. 너 왜 추가하는거야? 너 왜 추가하고있어? 추가되면 어떤 일이 발생해야합니까? 모든 대화를로드하는 이유는 무엇입니까? 사용자가 압도적 인 UI 경험 일 수있는 200 개가있는 경우 귀하의 질문을 명확히 해주시기 바랍니다. – Jay

+0

User1과 User2가 대화를하면 위에 제공된 구조로 텍스트가 firebase에 전송됩니다. 이 두 사용자가 20 개의 메시지를 보내면 두 명의 사용자간에 마지막 메시지를 보내고이를 tableviewcell에 표시하고 싶습니다. User1 중 하나가 다른 사용자 3에게 4 개의 메시지를 보내는 경우 해당 사용자간에 마지막으로 보낸 메시지를 다시 가져 와서 tableview에 표시하려고합니다. 이제 user1에는 두 개의 tableview 셀이 있고 user2에는 1이 있고 User3에는 tableviewcell이 있습니다. @Jay – juelizabeth

답변

0

질문에 코드의 문제는 그 쿼리가 "센더"(문자 문자열 센더)의 값이 메시지/ReceiverId 노드를 조회하려고이

queryEqual(toValue: "senderId") 

입니다. 대신 실제 uid를 쿼리해야합니다.

func loadData() 
{ 
    let uidToFind = "hx1DX1hW5JZMSmDjwQRUYo3i5Yt2" 
    FIRDatabase.database().reference().child("messages") 
         .queryOrdered(byChild: "ReceiverId") 
         .queryEqual(toValue: uidToFind) 
         .observe(.childAdded, with: { snapshot in 

     let msgDict = snapshot.value as! [String: Any] 
     let msg = msgDict["ReceiverId"] as! String 
     self.messages = [] 
     self.messages.append(msg) 
     self.MessageTableView.reloadData() 
    }) 
} 

이 코드가 작동하는 동안, 그것은, ReceiverId = UID와 일치하는 모든 자식 노드를 반복하는 그들에게 한 번에 하나씩로드하고 이후에 추가 된 새 자식 노드에 대한 관찰자를 떠나고 있음을 강조한다.

배열을 여러 값으로 채울 수 있고 새 값에 대한 수신기를 연결할 수 있으므로 좋은 방법입니다.

그러나 실제로 가장 최근 게시물에만 관심이있는 경우 쿼리와 일치하는 마지막 노드 만 반환하는 queryLimitedToLast (1)을 사용하는 것이 좋습니다.

var messages = [String]() 
func loadData() 
{ 
    let uidToFind = "hx1DX1hW5JZMSmDjwQRUYo3i5Yt2" 
    FIRDatabase.database().reference().child("messages") 
         .queryOrdered(byChild: "ReceiverId") 
         .queryEqual(toValue: uidToFind) 
         .queryLimited(toLast: 1) 
         .observe(.childAdded, with: { snapshot in 

     let msgDict = snapshot.value as! [String: Any] 
     let msg = msgDict["ReceiverId"] as! String 
     self.messages = [] 
     self.messages.append(msg) 
     //self.MessageTableView.reloadData() 
     print(self.messages) //this will print the last msg and any new msgs 
    }) 
} 
+0

이것이 작동하지 않습니다. 하루 종일 시험해 보았지만 작동하지 않습니다. convoId를 포함하도록 데이터베이스를 업데이트했습니다. 바라건대, 이제는 동일한 convoId를 가진 메시지 만 추가하고 마지막 메시지를 출력 할 것입니다. – juelizabeth

+0

@juelizabeth 그 코드는 동일한 Firebase 구조를 가진 새로운 프로젝트에서 곧바로 (복사하여 붙여 넣기) 제공됩니다. 작동하지 않는 경우 어딘가에 오타가 있거나 데이터베이스가 초기화되지 않았거나 작동하지 못하는 규칙이있을 수 있습니다. 어떤 코드인지는 모르겠지만 코드는 확실히 작동합니다. – Jay

+0

전체보기 컨트롤러가 어떻게 보이는지 코드를 업데이트했습니다. 특정 사용자 메시지를 검색하고 싶지 않습니다. 그래서 ConvoId를 포함 시켜서 두 사용자 사이의 메시지가 고유 ID를 가지며 추가 할 수 있습니다. – juelizabeth

관련 문제