0

I have tried everything but data is not coming in order , even snapshot is showing data in unordered form

I'm developing chat app. i want to maintain the order of the data so chat must show in order, but its not happening. whenever i send message it placed between the old messages not in the bottom

Here the latest message "what are you doing?"

enter image description here

here's the chat. look where is that latest message "what are you doing?"

enter image description here

my code for observing messages

public func getAllMessagesForConversation(with id: String, completion: @escaping (Result<[Message], Error>) -> Void) {
  
    database.child("\(id)").queryOrdered(byChild: "date").observe(.value) { (snapshot) in
        guard let value = snapshot.value as? [String:Dictionary<String, Any>] else{
            completion(.failure(DatabaseError.failedToFetch))
            return
        }

        var messages = [Message]()
        for i in value {
            
            guard let message = i.value["message"] as? String else {return}
            
            let senderId = i.value["sender"] as? String
            let recieverId = i.value["reciever"] as? String
            let messageID = i.value["id"] as? String
            var DATE = Date()
            if let date = i.value["date"] as? String {
                DATE = ChatViewController.dateFormatter.date(from: date)!
            }
            var kind: MessageKind?
            
            kind = .text(message)
                
                let finalKind = kind
                
                let sender = Sender(photoURL: "",
                                    senderId: senderId!,
                                    displayName: Api.Params.inputUserName)
                
                let abc = Message(sender: sender,
                            messageId: messageID ?? "",
                            sentDate: DATE,
                            kind: finalKind!)
                
                messages.append(abc)

            if messages.count == value.count {
            messages = messages.sorted(by: { (lhs, rhs) -> Bool in
                lhs.sentDate.toMillis() > rhs.sentDate.toMillis()
            })
            }
            print(messages)
        }

        completion(.success(messages))
    }
}
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Hanzala Raza
  • 149
  • 1
  • 16
  • When you call `snapshot.value` the keys and values are returns as a dictionary, which means it loses information about ordering. To retain this information, you need to loop over `snapshot.children` instead. See https://stackoverflow.com/questions/40166483/firebase-getting-data-in-order/40168370#40168370 – Frank van Puffelen Jul 27 '20 at 14:57

1 Answers1

1

The problem is probably that you did not include key "date" to be indexed in firebase.

Go to firebase console database, go to Rules tab, enter and save:

"emantrasports":{
   "$conversationID": {
     ".indexOn": ["date"]
   }
}

enter image description here

There is a different approach to order your data on client side.

Firstly you need to create a model of your Message, that contains all necessary variables and also a date variable. And then order your array of message objects by your date variable.

Pete Streem
  • 360
  • 5
  • 14
  • Thanks bro for the response , In Firebase rules , i have read and write options , where should i add this code ? Under which body ? – Hanzala Raza Jul 27 '20 at 13:49
  • 1
    @HanzalaRaza I updated my answer with image. Check it out. – Pete Streem Jul 27 '20 at 14:49
  • ok understood , one thing i need to ask how can i reference that childbyautoID ? how did you find that $conversationID could be used in place of childbyautoID ? – Hanzala Raza Jul 27 '20 at 18:44
  • 1
    @HanzalaRaza You can get child auto id by accessing key value. In your case it's - i.key – Pete Streem Jul 29 '20 at 15:53
  • awesome , thanks alot , could you help me regarding messageKit ? whenever i comes on the chat screen my msgs always comes outside the viewController (Behind Navigation bar) , I always need to scroll down for correct alignment .... Check the edit – Hanzala Raza Jul 29 '20 at 22:09
  • @HanzalaRaza Sorry, I don't know usage of Message Kit. As an idea - you can set collection view top inset to something like - 16 or 24. collectionView.contentInset = UIEdgeInsets.init(top: 16, left: 0, bottom: 0, right: 0) – Pete Streem Jul 30 '20 at 10:40