Having Proper Message Functionality with Parse, UIKit and MessageKit

For my iOS Social Media App project, I am currently working on the Direct Messaging feature of the app. As of making this post, I have the basic functionality working where you can send messages to other users in the app. However, there are a few issues I am experiencing.

1.) Being able to see the other user’s texts and replies. I can send a message to the user but said user won’t be able to see it and vice versa for some reason I haven’t been able to fetch and load chat history properly.

2.) The chats don’t have their own unique messages. If I send a message to one user, it shows up in my chats with other users as well rather than each chat having its own unique messages.

They both seem to be issues related to fetching saved data from my Parse Cloud. The messages are saved properly to the cloud but fetching them and displaying them seems to be the issue.

Here is my code associated with Messaging:

import UIKit
import MessageKit
import Parse

class DirectMessagingViewController: UIViewController, UITableViewDelegate, UITableViewDataSource
{   var otherUsers = [PFUser]()
    var currentUser: PFUser!
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return otherUsers.count
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = otherUsers[indexPath.row].username
        cell.accessoryType = .disclosureIndicator
        return cell
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        // Show chat messages
        let vc = ChatViewController()
        vc.title = otherUsers[indexPath.row].username
        navigationController?.pushViewController(vc, animated: true)
    @IBOutlet var myTable: UITableView!
    override func viewDidLoad()
           myTable.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
           myTable.delegate = self
           myTable.dataSource = self
           // Get current user
           currentUser = PFUser.current()
           // Query for other users
           let query = PFUser.query()
           query?.whereKey("objectId", notEqualTo: currentUser.objectId!)
           query?.findObjectsInBackground(block: { (users, error) in
               if let users = users as? [PFUser] {
                   self.otherUsers = users
               } else {
                   print("Error querying for users: \(error?.localizedDescription ?? "")")
import UIKit
import MessageKit
import InputBarAccessoryView
import Parse

struct Message: MessageType
    var sender: SenderType
    var messageId: String
    var sentDate: Date
    var kind: MessageKind

class ChatViewController: MessagesViewController, MessagesDataSource, MessagesLayoutDelegate, MessagesDisplayDelegate, InputBarAccessoryViewDelegate
    let currentUser = PFUser.current()!
    var otherUser: PFUser!
    var messages = [MessageType]()
    override func viewDidLoad() {
        // Set up the other user
        let query = PFUser.query()
        query?.whereKey("objectId", notEqualTo: currentUser.objectId!)
        query?.findObjectsInBackground(block: { (objects, error) in
            if let users = objects as? [PFUser], let user = users.first {
                self.otherUser = user
                // Retrieve previous messages from Parse
                let messageQuery = PFQuery(className: "Message")
                messageQuery.whereKey("sender", equalTo: self.currentUser)
                messageQuery.whereKey("recipient", equalTo: self.otherUser!)
                let recipientQuery = PFQuery(className: "Message")
                recipientQuery.whereKey("sender", equalTo: self.otherUser!)
                recipientQuery.whereKey("recipient", equalTo: self.currentUser)
                let query = PFQuery.orQuery(withSubqueries: [messageQuery, recipientQuery])
                query.findObjectsInBackground { (objects, error) in
                    if let messages = objects {
                        for message in messages {
                            let sender = message["sender"] as! PFUser
                            let text = message["text"] as! String
                            let sentDate = message.createdAt!
                            let messageKind = MessageKind.text(text)
                            let messageSender: Sender
                            do {
                                try sender.fetchIfNeeded()
                                messageSender = Sender(senderId: sender.objectId!, displayName: sender.username ?? "")
                            } catch {
                                messageSender = Sender(senderId: sender.objectId!, displayName: "Unknown")
                                print("Error fetching sender: \(error.localizedDescription)")
                            let message = Message(sender: messageSender, messageId: message.objectId!, sentDate: sentDate, kind: messageKind)
                            print("Fetched previous messages!")
                        self.messagesCollectionView.scrollToLastItem(animated: false)
        // Configure the messages collection view and input bar
        messagesCollectionView.messagesDataSource = self
        messagesCollectionView.messagesLayoutDelegate = self
        messagesCollectionView.messagesDisplayDelegate = self
        messageInputBar.delegate = self
        messageInputBar.inputTextView.placeholder = "Type a message..."
        messageInputBar.sendButton.setTitle("Send", for: .normal)
        messageInputBar.sendButton.setTitleColor(view.tintColor, for: .normal)
        messageInputBar.sendButton.addTarget(self, action: #selector(sendButtonPressed), for: .touchUpInside)
    func currentSender() -> SenderType
        return Sender(senderId: currentUser.objectId!, displayName: currentUser.username ?? "")
    func numberOfSections(in messagesCollectionView: MessagesCollectionView) -> Int
        return messages.count
    func messageForItem(at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> MessageType
        return messages[indexPath.section]
    @objc func sendButtonPressed() {
        let messageText = messageInputBar.inputTextView.text.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !messageText.isEmpty else {
        let message = Message(sender: currentSender(), messageId: UUID().uuidString, sentDate: Date(), kind: .text(messageText))
        messageInputBar.inputTextView.text = ""
        messagesCollectionView.scrollToLastItem(animated: true)
        print("Message sent!")
        // Save the message to Parse
        let parseMessage = PFObject(className: "Message")
        parseMessage["sender"] = currentUser
        parseMessage["recipient"] = otherUser
        parseMessage["text"] = messageText
        parseMessage.saveInBackground { (success, error) in
            if success {
                print("Message saved!")
            } else if let error = error {
                print("Error saving message: \(error.localizedDescription)")
    func inputBar(_ inputBar: InputBarAccessoryView, textViewTextDidChangeTo text: String)
        if text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
            inputBar.sendButton.isEnabled = false
        } else
            inputBar.sendButton.isEnabled = true
    func inputBar(_ inputBar: InputBarAccessoryView, didPressSendButtonWith text: String)

The DirectMessageViewController() loads all the users you can chat with and displays the conversation with a user when you tap on that user. The ChatViewController() is what handles the functionality regarding sending messages, saving them to the Parse Cloud, and fetching them. All help would be greatly appreciated!