Search code examples
iosswiftfirebasefirebase-realtime-databasejsqmessagesviewcontroller

JSQMessagesViewController and Firebase


I am using Firebase and JSQMessagesViewcontroller. I add some message to test but didn't show up. Can anyone help to see what I have missed? Thanks!

enter image description here

My Code:

import UIKit
import Firebase
import JSQMessagesViewController

class ChatViewController: JSQMessagesViewController {

var messages = [JSQMessage]()

lazy var outgoingBubbleImageView:JSQMessagesBubbleImage = self.setupOutgoingBubble()
lazy var incomingBubbleimageView:JSQMessagesBubbleImage = self.setupIncomingBubble()


override func viewDidLoad() {
    super.viewDidLoad()

    self.senderDisplayName = "cindy"
    self.senderId = FIRAuth.auth()?.currentUser?.uid

    print("sender id is: \(self.senderId)")
}

override func viewDidAppear(_ animated: Bool) {

    addMessage(withId: "john", name: "doo", text: "hello, I am here")

    addMessage(withId: senderId, name: "Me", text: "how are you")

    addMessage(withId: senderId, name: "Me", text: "i am earlier than you.")

   // I added finishReceivingMessage() here, but the app crashed.

}

override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return messages.count
}

override func collectionView(_ collectionView: JSQMessagesCollectionView!, messageDataForItemAt indexPath: IndexPath!) -> JSQMessageData! {

    return messages[indexPath.item]
}

override func collectionView(_ collectionView: JSQMessagesCollectionView!, messageBubbleImageDataForItemAt indexPath: IndexPath!) -> JSQMessageBubbleImageDataSource! {

    let message = messages[indexPath.item]

    if message.senderId == senderId {

        return outgoingBubbleImageView
    } else {

        return incomingBubbleimageView
    }
}

func addMessage(withId id:String, name: String, text:String) {

    if let message = JSQMessage(senderId: id, displayName: name, text: text) {

        self.messages.append(message)

    }

}

func setupOutgoingBubble() -> JSQMessagesBubbleImage {

    let bubbleImagesFactory = JSQMessagesBubbleImageFactory()

    return (bubbleImagesFactory?.outgoingMessagesBubbleImage(with: UIColor.jsq_messageBubbleBlue()))!

}

func setupIncomingBubble() -> JSQMessagesBubbleImage {

    let bubbleImagesFactory = JSQMessagesBubbleImageFactory()

    return (bubbleImagesFactory?.incomingMessagesBubbleImage(with: UIColor.jsq_messageBubbleLightGray()))!
 }

}

Solution

  • So for starters I would suggest that you go and checkout the Develop branch of JSQMessagesVeiwController and pull up the SwiftExample contained within. This is the latest version and has been updated for swift3. Then I would isolate your issues. Since you are actually makeing the messages locally and not leveraging firebase I would Comment that out.

    Then we can make your fake conversation like they do in the DemoConversation.swift file

    let message = JSQMessage(senderId: "john", displayName: "doo", text: "hello, I am here")
    let message2 = JSQMessage(senderId: "asdf", displayName: "Me", text: "how are you")
    let message3 = JSQMessage(senderId: "asdf", displayName: "Me", text: "i am earlier than you.")
    
    
    func makeNormalConversation() -> [JSQMessage] {
      conversation = [message, message2, message3]
      return conversation
    }
    

    Then you just need to make sure you have everything setup for you view and set your messages to makeNormalConversation()

    Then for your ChatViewController the minimum amount of code is this:

    //
    //  ChatViewController.swift
    //  SwiftExample
    //
    //  Created by Dan Leonard on 5/11/16.
    //  Copyright © 2016 MacMeDan. All rights reserved.
    //
    
    import UIKit
    import JSQMessagesViewController
    
    class ChatViewController: JSQMessagesViewController {
      var messages = [JSQMessage]()
      let defaults = UserDefaults.standard
      var conversation: Conversation = makeConversation() // Here is where your messages are added.
      var incomingBubble: JSQMessagesBubbleImage!
      var outgoingBubble: JSQMessagesBubbleImage!
      fileprivate var displayName: String!
    
      override func viewDidLoad() {
        super.viewDidLoad()
            incomingBubble = JSQMessagesBubbleImageFactory().incomingMessagesBubbleImage(with: UIColor.jsq_messageBubbleBlue())
            outgoingBubble = JSQMessagesBubbleImageFactory().outgoingMessagesBubbleImage(with: UIColor.lightGray)
    
            collectionView?.collectionViewLayout.incomingAvatarViewSize = .zero
            collectionView?.collectionViewLayout.outgoingAvatarViewSize = .zero
    
        automaticallyScrollsToMostRecentMessage = true
    
        self.collectionView?.reloadData()
        self.collectionView?.layoutIfNeeded()
      }
    
    
      // MARK: JSQMessagesViewController method overrides
      override func didPressSend(_ button: UIButton, withMessageText text: String, senderId: String, senderDisplayName: String, date: Date) {
        let message = JSQMessage(senderId: senderId, senderDisplayName: senderDisplayName, date: date, text: text)
        self.messages.append(message)
        self.finishSendingMessage(animated: true)
      }
    
      // MARK: JSQMessages CollectionView DataSource
    
      override func senderId() -> String {
        return "Cindy"
      }
    
      override func senderDisplayName() -> String {
        return "Cindy Lue"
      }
    
      override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return messages.count
      }
    
      override func collectionView(_ collectionView: JSQMessagesCollectionView, messageDataForItemAt indexPath: IndexPath) -> JSQMessageData {
        return messages[indexPath.item]
      }
    
      override func collectionView(_ collectionView: JSQMessagesCollectionView, messageBubbleImageDataForItemAt indexPath: IndexPath) -> JSQMessageBubbleImageDataSource {
    
        return messages[indexPath.item].senderId == self.senderId() ? outgoingBubble : incomingBubble
      }
    
    }
    

    Check out the example project on the develop branch for more details and let me know if you have more questions?

    Then from this point you should add Firebase. You were on the right path for the senderID just make sure you actually get a unique id for the user that has logged in and then make sure it is the same ID for the messages sent by that user.

    Good luck 🖖🏽