I have a global chat that allows any can see what everyone has typed, their name and icon. I have 2 approaches in mind on how to structure the data but I'm not sure which one of these is the best in terms of data cost.
First approach:
root
chat
messageId
userName
userIcon
text
Second approach:
root
chat
messageId
userId
text
root
profiles
userId
name
icon
With second approach, I then fetch the userId in a public profiles node that contains all users' names and icons. Which one is should I go for?
Related
What would be the best way to uniquely identify an MSConversation when developing an iMessages application?
In my case I want to give to a game object an ID of the conversation where it belongs to.
Take the localParticipant ID, add to it the remoteParticipants ID ;)
Something like that :
var conversationID = yourConversation.localParticipantIdentifier
for participant in yourConversation.remoteParticipantIdentifiers {
conversationID += participant
}
EDIT:
As noticed in comments, by doing so, you could end up with a very long ID. So the idea is to apply an hash to it, to have a constant size (MD5 is suffisant, we don't need something secure here). If it is still too long, you could crop that hash, but be aware that in that case there is a small probability for two conversations to have the same ID (depending on how much your crop).
The current top answer has a corruption issue in that if a new person is added to a group chat (or if someone is removed) your hashed ID will change.
A more elegant solution in my opinion is to just create your own serial number at the time of the first message being created and add it as meta-data to your message itself. (Using NSURLComponents of course). Then just grab that anytime a message is opened (thus launching your message app) and use that ID. Just keep it in the header of any message sent/received.
But, it depends on what you are trying to do really. The solution I've provided is great for turn-based multi-player games. It might not be good for other scenarios.
In my app to check for if an email (and username) is taken when signing up I use queries like this...
let emailRef = Firebase(url: "https://photocliq5622144.firebaseio.com/users")
emailRef.queryOrderedByChild("email").queryEqualToValue(email.text!.lowercaseString).observeEventType(.Value, withBlock: { email in
Would this work well with hundreds or even thousands of users (is this scalable)?
Hundreds: yes
Thousands: yes
Tens of thousands... probably (and congratulations on the success of your app)
Hundreds of thousands... you're likely better off with a non query-based data model. For example: if you want to access some data for the user by their email address, store a map from email address to uid:
emailToUid
"HelixProbe#stackoverflow,com": "uid6479958"
"puf#stackoverflow.com": "uid209103"
With such a simple list, you can read the user's data from their email address with two direct lookups, instead of one query (which will get slower as more and more items are added).
Scalable or not is determined by your user.
Behind the scene Firebase library is just downloading JSON string and you know exactly what happen if the string is too long and the file size to be downloaded reach (for example 3MByte)
If your user is able and okay with 3MByte for a request, than you can go with it. But I don't if I am your user.
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.
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 :)
I have a simple question
I'm developping a chat system service but I came across something interesting.
I'm currently operating this way :
First table :
[Messages] :
SenderID(user),
RecipientID(user),
Content(string)
Of course, everytime a user sends a message to the other user, I add it to the table. But I thought about the fact that If a table has a million lines, it would become a mess
So I thought about another way being :
First Table :
[Conversation]
ConversationID,
USER1(user),
USER2(user)
Second table :
[Messages] in which I have
ConversationID,
Content(string)
So basically, I'm asking, which configuration should I use?
The approach below should be able to sort you out. This is a good basis for both chat and messaging, where with chat you can poll recent messages from the client side and slap on an intuitive UI.
Message
Message {
MessageId,
FromId, -- Foreign key User.UserId
ToId, -- Foreign key User.UserId
Subject,
Content,
Attachment, -- can be null or default to a 0
DateReceived, -- can be null or default to 1901 or sumin'
DateRead
...
}
User
User {
UserId
UserName
...
}
Queries
Inbox = Message where ToId = Me.UserId
Sent = Message where FromId = Me.UserId
Conversation = Group by Subject
Attachment = (Simple = Path to attachment file. || Better = DocumentId)
Attachment
Document {
int DocumentId,
int DocTypeId,
virtual DocumentType DocumentType,
string FileName,
int UserId,
string mimeType,
float fileSize,
string storagePath,
int OrganizationId,
string fileHash,
string ipAddress,
DateTime DateCreated = DateTime.Now;
}
Then you run into the issue with group chats. Do you send a message to each recipient of the group or do you create a single message that each recipient has access to?
But we're keeping it simple.
Here is another idea, Store the notion of a "message". Whether it be an email, text, sms or sound file. this is where you would store the message text and or other metadata. Think of the "message" as everything up to releasing the stop talk button on a walkie-talkie to end the transmission and everything up until the start and stop has been stored in the "message". This message could be tied to other messages by the fact that the user was replying to a "message" from a prior party's request to talk.
If you wanted to make the whole relationship easy then you could log the "messages" sent to a user, "inbox" and messages sent from a user, "outbox". This is synonymous with today's messaging mentality.
Message
MessageID,
Subject,
Content
...
MessageReceived
MessageReceivedID,
UserID,
FromUserID,
MessageID,
DateReceived,
DateRead,
MessageSent
MessageSentID,
UserID,
MessageID,
DateSent,
DeletedStatusID
Both solutions work for simple messaging. The question here really is if there is ever more than one conversation context of messages that should exist between the same two users.
If two users are always talking within the scope of the same conversational context/history every time they being chatting, your first solution is sufficient. Think of this scenario like a Skype chat. It's just one long conversation over time.
If conversational context changes when they begin chatting (i.e. their chat history never really persists between two different days worth of conversations), solution two makes more sense. Think of this scenario like an email between two users. The next day I could write another email to the same person, but it is a different conversation.
Also for solution two, you would also need to add USER to the second table to track which user sent the message in the conversation:
First Table :
[Conversation]
ConversationID,
USER1(user),
USER2(user)
Second table :
[Messages]
ConversationID,
Content(string)
USER(user)
In summary, just because a table would have millions of lines doesn't mean it's not the correct way of doing it. In this case, it just depends on the requirements of your application.
I am building an application that I will need to distinguish the Google Contacts from each other. I am just wondering, as long as google sends contacts as First Name/Last Name/mail.. etc (Example) without a unique ID, what will be the first approach to distinguish each contacts?
1) Should I create an ID based on the user's fields? -> by a minimal change, it can break down.
2) Should I create an ID based on First Name + Last Name? -> but most people can have duplicate contacts on their page, would that be a problem? Or married contacts, which can create a little mess.
The reason I am asking this I am trying to create relations and I need to store the data somewhere like that [person=Darth Vader, subject=Luke Skywalker, type=father(or son)], so I need a fast algorithm that can make a mapping for each contact and retrieve the related contacts fast.
I believe they do send back an ID. From the return schema:
<link rel='self' type='application/atom+xml' href='https://www.google.com/m8/feeds/contacts/userEmail/full/contactId'/>
You could use the full HREF value as the ID, or parse out the contactID from the end of the URL, whichever you like better.