4
votes

I'm implementing chat logic 1-1 in my iOS app. I'm using firebase to store chats and messages in chats. Messages are working great. But I have some difficulties with chats list. My structure of stored chats looks like this

-Users
--UserID
---chatrooms 
----chatroomID
-----updatedTime
-----deleted
-----read
-----receiverID
-----receiverName

I store in NSUserDefaults NSDate value "chatsLoadedTime". I query chats by sending query:

var time: String?
if defaults.valueForKey("chatsLoadedTime") != nil {
    time = "\(defaults.valueForKey("chatsLoadedTime") as! NSDate)"
}
chatsRef.queryOrderedByChild("createdTime").queryStartingAtValue(time).observeEventType(.Value, withBlock: { snap in
    defaults.setValue(toLocalTime(NSDate()), forKey: "chatsLoadedTime")
and so on
.
.
.

As far as I can see it is a good way to store chats and be able to download chats from different devices. For example I have just installed the app, my chatsLoadedTime value is nil, then I download all chats and update this value to current dateTime. If new chat created, then its createdTime is bigger then my chatsLoadedTime value and the app will download it.

But I don't know how to implement a good and efficient way to delete chat. I want this logic: if user1 delete chat, then he just change his value deleted=true. If second user also delete this chat at his side, then the chat and the messages will be totally removed from the app. If user1 deleted chat, but user2 not, then if user2 write to user1, then user1 receives this messages and all previous, because messages weren't deleted. But maybe it is not the best logic. Give m, please an advice how to do this in the best way.

If I could, I would want to query on multiple values, but as far as I know it is not possible.

1
It seems that everything is working as you want except deleting? You could add a deletedChats node within each UserID. When a chat is deleted write chatroomID: true to each users UserId/deletedChat node. When another user deletes a chat, query that node for the chatroomID and if it exists, then remove the chat completely. If not, then set chatroomID: true - Jay
it seems to long. What if user1 deleted chat, but then user2 writes to user1. Then I need to send query, receive snapshot, check if user2 has a deletedChat node. If he has then i have to remove this node, if not, then just write. - Taras Nikulin
Maybe I've created the solution. I'll answer later :) - Taras Nikulin
You don't even need to query, just do a observeSingleEventOfType since you know the specific node name - that's pretty low overhead. Another simple solution would be if user 2 writes to the chat, set UserId/deletedChats/chatroomID = nil. If it exists it will be removed by Firebase since it's nil, if not, nothing will happen. - Jay
maybe you know how to change query starting value? for example i send query like this: chatsRef.queryOrderedByChild("updatedTime").queryStartingAtValue(time).observeEventType(.Value, withBlock: { snap in And inside query i change time to another value, how can i update query? - Taras Nikulin

1 Answers

0
votes

I've added updatedTime value to every chatRoom. And I've added a value to device called lastLoadedTime. Every time when i receive snapshot from firebase i update lastLoadedTime to current time. So, I observe chats, where time value stored on the device is smaller than updatedTime in chatRoom in firebase. When i delete chat i set updated time to 1990-01-01 00:00:00. So i won't observe this chat until somebody send me a message. Ask me if you need more information to understand :)