0
var chatMessages = [[String: ChatMessage]]()

Firebase Chat Messages structure is like this.

-Kjws99ol6qjFt7ET9C
     content: "Hehd"
     displayName: "John Doe"
     fileLength: 0
     fileUrl: ""
     fromID: "5904ee8cfa"
     isRead: false
     messageStatus:  2
     messageType: "normal"
     timestamp: 1494596232

Now on childAdded I'm appending the new message like this

weakSelf.chatMessages.append(newMessage)

//Kjws99ol6qjFt7ET9C - This is the threadID which is stored in String and below value is stored in ChatMessage

But after message isRead by user it value changes and that is identified by childChanged so in childChanged change how to update my Array correctly?

2 Answers 2

1

On the childChanged event, the app is passed a snapshot of the updated child, with the (in this case) key being Kjws99ol6qjFt7ET9C and the value being the child node data.

To update the array, find which index in the chatMessages array corresponds to that key and update the value accordingly.

To find it in the array you've set up, which is an array of [String: ChatMessage] dictionaries do the following

let searchKey = "Kjws99ol6qjFt7ET9C"
let index = chatMessages.map( {$0.keys.first!} ).index(of: searchKey)

Once you have the index, you can then update the element in the array with the new data.

{$0.keys.first!} - compiles all of the keys in the chatMessage array into an array

index(of: searchKey) - finds the index of the searchKey we are looking for

Then you can

chatMessage[index] = updated data

If you need any additional code, let me know.

However, I would strongly encourage changing the model to store a ChatMessage class (or struct) in the array

class ChatMessage {
   var fbKey = ""      // the key like Kjws99ol6qjFt7ET9C
   var content = ""    // like "Hehd"
   var displayName ""  // "John Doe"
}

var chatMessages = [ChatMessage]()

it will be easier to maintain and the array search is simplified and faster.

With this use case, to find a specific index do this

let searchKey = "Kjws99ol6qjFt7ET9C"
let index = chatMessages.index(where: { $0.fbKey == searchKey} )
Sign up to request clarification or add additional context in comments.

3 Comments

class ChatMessage() { fbKey = "" // the key like Kjws99ol6qjFt7ET9C content = "" // like "Hehd" displayName "" // "John Doe" } But by having key in ChatMessage() how I would identify it directly on change?
Updated the answer with code to find the message using my recommended solution with classes instead of the dictionaries.
Thanks. Got your idea.
0

I'm confused as to why you are storing the dictionary inside an array. It looks to me like

var chatMessages = [String: ChatMessage]()

would satisfy your model as each message push id (e.g. -Kjws99ol6qjFt7ET9C) would be unique from the database, so you could have a valid Dictionary by storing this push id as the key.

When you receive a childChanged event, you can then quickly locate the message that has changed by looking up the snapshot.key in the dictionary and updating it.

8 Comments

var chatMessages = [String: ChatMessage]() does not let me store multiple messages. I mean appending data.
what about chatMessages["newId"] = ChatMessage()?
It needs indexPath. like chatMessages[0]["newId"]
You can sort by chatMessages.keys and then parse into an array if you're planning to map chatMessages to TableViewCells or similar.
Yes i tried having array with theadID only but that also didnt worked as I would need indexPAth of where I should update it
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.