2017-05-19 1 views
0

Ich erstelle eine Chat-App und ich habe eine Liste aller Nachrichten, die zwischen zwei Benutzern in einer Tabellenansichtszelle gesendet werden. Zum Beispiel habe ich vier Texte insgesamt zwischen den zwei Benutzern und so habe ich vier Zellen. Allerdings möchte ich die Zellen so gruppieren, dass ich nur eine Zelle habe, weil ich mit dem loggedInUser nur mit einer Person kommuniziere. Egal was ich mache, die Nachrichten werden nicht angehängt.Firebase-Chatnachrichten anhängen

func loadData(){ 
if (FIRAuth.auth()?.currentUser) != nil{ 

FIRDatabase.database().reference().child("messages").observeSingleEvent(of: .value, with: { (snapshot:FIRDataSnapshot) in 

let loggedInUserData = snapshot 
if let postsDictionary = snapshot .value as? [String: AnyObject] { 

for post in postsDictionary { 
    let messages = post.value as! [String: AnyObject] 
    for (id, value) in messages { 
     let info = value as! [String: AnyObject] 
     if let receiver = info["ReceiverId"] { 
     print("\(id): \(receiver)") 
     self.messages.Array(value) 

     } 

    } 
    self.MessageTableView.reloadData() 
} 


}})} 
} 

Wie jetzt meiner App-Nachrichten zwischen zwei Benutzern wie folgt dargestellt: enter image description here

ich glaube, das Thema in der self.messages.Array(value) ist, ich muss nur Nachrichten zwischen den gleichen zwei Benutzer anhängen, aber ich kann‘ t finden sie den richtigen Code

Aber ich würde für ein Gespräch zwischen zwei Benutzern wie in einer Zelle zu sein (append it) enter image description here

Dies ist, was meine Zelle aussieht :

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 
    // cell.SellerName.text = message["ReceiverId"] 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 { 

           print("Error downloading image:") 


          }})} 

        self.messages.add(value) 
       } 
      } 


     } 

    }) 
    } 

    return cell 
} 

mein Weg zu Feuerbasis Nachricht ist:....

FIRDatabase.database() Referenz() Kind ("Nachrichten") Kind ("! (Self.convoId)") childByAutoId ()

Hier ist meine Datenbankstruktur: enter image description here

+0

Offtopic, aber warum würden Sie ein einzelnes Ereignis beobachten und nicht Kind hinzugefügt?Auf diese Weise werden alle alten und neuen Nachrichten heruntergeladen. –

+0

@ J.Doe es funktioniert gut. Ich habe kein Problem mit den alten und neuen Nachrichten heruntergeladen werden – juelizabeth

+0

Bitte erklären Sie etwas. Sie möchten, wie wenn ich 4 Nachrichten in der Reihenfolge sende, sollten sie sich anfügen, um nur eine Zelle zu sein? –

Antwort

1

hilft ich ein Super einfaches Beispiel in meiner Antwort verwenden. von uid_0:

eine Struktur

messages 
    msg_0 
     rec: "uid_0" 
     send: "uid_1" 
     msg: "msg from uid_0 to uid_1" 
    msg_1 
     rec: "uid_1" 
     send: "uid_0" 
     msg: "msg from uid_1 to uid_0" 

hinzufügen Abfrage Beobachter an den Knoten für neue Nachrichten (.childAdded), die eine rec haben gerade Nachrichten gegeben.

var messagesArray = [String]() 

func watch() { 
    let messagesRef = self.ref.child("messages") 
    let queryRef = messagesRef.queryOrdered(byChild: "rec").queryEqual(toValue: "uid_0") 

    queryRef.observe(.childAdded, with: { snapshot in 

     let msgDict = snapshot.value as! [String: Any] 
     let msg = msgDict["msg"] as! String 

     self.messagesArray = [] //erases the array 
     self.messagesArray.append(msg) //adds this new message at index 0 

     print(self.messagesArray) //print is just for example 
     //normally call tableView.reloadData() which will refresh 
     // the cells in the tableView and display just once cell with 
     // the latest message in it 
    }) 
} 

Sie können aus dieser extrapolieren durch den Schnappschuss oder das Wörterbuch in dem Array zu speichern, so dass Sie den Nachrichtentext kennen und die Sende verwenden können: Benutzer-ID zu suchen, die die Nachricht gesendet hat.

Wenn Sie diesen Code ausführen, wird die Ausgabe eine neue Nachricht sein, die an uid_0 gesendet wird; Nur die letzte Nachricht wird angezeigt. Wenn Sie eine Tabelle mit dem messagesArray als dataSource haben (was normalerweise der Fall ist), dann würde die tableView aktualisiert werden und immer nur die letzte Nachricht für uid_0 anzeigen.

Als eine Randnotiz konnte .queryLimited (toLast :) hier gut genutzt werden.

+0

platzieren, weil es schwierig ist, auf den ConvoId-Knoten zuzugreifen, bin ich mir nicht sicher, wo genau .queryLimited (toLast :) – juelizabeth

+0

@juelizabeth Sie wirklich brauchen nicht, dass mit dem Code, den ich zur Verfügung gestellt - mein Code wird getestet, funktioniert und bietet eine Lösung. Selbst wenn Sie .queryLimited verwendet haben, ist der Code fast identisch. Geh mit, wenn ich gepostet habe und lass es zuerst funktionieren. Wenn du es später ändern willst, wirst du den Fluss besser verstehen. (Was ist * convold *?) Wenn meine Lösung hilft, sollten Sie sie akzeptieren, damit sie anderen helfen kann! – Jay

0

1) denke ich, dass in Ihrem Fall sollten Sie .queryLimited (toLast: 1), um Nachrichten zu jedem Chat. Und wenn Details geöffnet sind - laden Sie andere Nachrichten.

2) Aber ich habe eine Vermutung, dass Sie falsche Datenbankstruktur haben. Check this

Hier finden Sie eine gute Struktur der Datenbank für Chat von Firebase Docs Autoren.

Sie können auch diese alten Auszüge App macht Chat überprüfen: Link

Hoffen, dass es

+0

Begrenzung der Abfrage auf 1 machte keinen Unterschied, ich habe immer noch vier Zellen – juelizabeth

+0

Ich denke, das Problem ist in der 'self.messages.Array (Wert)' Ich muss nur Nachrichten zwischen den die gleichen zwei Benutzer, aber ich kann nicht den richtigen Code finden – juelizabeth

+0

@juelizabeth Eigentlich denke ich, es ist besser, einige Untersuchungen in Ihrer db-Struktur zu tun. Aber warte, ich denke –