Here is what I want to do:
Users are getting logged in and then save data (such as thier e-mail, their work, their adress and so on). I saved this data at „/userProfile/exampleUID“. This works as I wnat it to.
Then every user should create his or her own story. Within this stories, mostly strings should be stored. A friend of mine told me, that it would be better to normalize my data, so I thought of saving the stories to „/storyData“. He also told me, that every Story has to have a unique identifier as well, which i create with .push(). Under this identifiers I want to store the users unique id (auth().currentUser.uid) to assign the story to the user who has created it. The strings for the stories should also be stored under the unique ID created by .push(). („/storyData/exampleStoryID/exampleUID“)
The problem is now that i can’t find a method to access this strings or the "/exampleUID". In this case I would need to skip the „/exampleStoryID“-child when creating a query, because without saving I would not know its name. Am I right or did I oversee the method for this?
There would be solutions to this:
I have to save the „.key“ of the „/exampleStoryID“ to the „/userProfile/exampleUID“. With this key I would not need to skip one child while querying, because I can enter this key to Access the data in /“storyData“.
I have to denormalize my data. For me, this would mean that I have to create a new child: „/userProfile/exampleUser/storyData“. Here I could save all the strings.
It may be possible that there will be more data like „/storyAnalysis“ and „/storyComments“. Having that in mind: Which solution should I prefer?
Or do you have other suggestions?
Thanks in advance.
MfG
Related
I have searched throughout stackoverflow looking for a way to generate numerical keys or any type of keys that are readable for the end user.
I have found multiple answers saying (you shouldn't). I get it .. but what's the alternative..
Imagine a customer having an issue regarding an Order for instance and having to spell the uid 1UXBay2TTnZRnbZrCdXh to your call center?
It's usually a good idea to disassociate keys from the data they contain. The data can change, usernames, passwords, locations etc. That kind of data is very dynamic. However, links and references are more static in nature.
Suppose you have a list of followers and you're using their username as a key. If a user changes his username, not only will their entire node have the be deleted and re-written, every other occurance of that key in the database would have the changed as well. Wheras, if the key is static, the only item that changes in the child username.
So to answer the question: here's one option
orders
firebase_generated_key_0
order_number: "1111"
ordered_by: "uid_0"
order_amount: "$99.95"
firebase_generated_key_1
order_number: "2222"
ordered_by: "uid_1"
order_amount: "$12>95"
With this structure you have the order number, a link to the user that ordered it and the total amount of the order. If the customer changes what's on the order, a simple change the order_amount is done and the order stays in place.
Edit:
A comment/question asked about race conditions when writing data with Firebase. There are a number of solutions but a good starting point is with Firebase Transactions to essentially 'lock' data to prevent concurrent modifications.
See Save data as transactions for further reading.
Question in short, how to easily update a value that is duplicated in multiple locations?
I have spent days to try to grab data structure design in firebase.
I have studied many resources like:
Firebase data structure and url
https://firebase.google.com/docs/database/web/structure-data
Then I got the point that duplicating some data to speed up read action is a key point in firebase.
A typical design: the user's display name shall be duplicated in multiple locations, like in article list, in comment list, in follower list, or following list, etc.. I cannot imagine not to duplicate this piece of data but async retrieve them one by one from users node.
What if a user updates his display name? It seems that we need to update the value in all places, which is a pain in butt to maintain in long term, isn't it?
Could you help to understand this approach:
I have to do a query that make some operations, i do not want to use containers, since i read that temporal tables are faster, at least for my case, but i dont get how it works:
The Web Service that i will use to make inserts in temporally table, will be consumed by some people in the same time, each values for each users will be diferents, because thats the reason why i want to do this.... but i dont understand how the temporal table, will manage data for each user; Because it will be only a table, so, if an user perform the WS, the table will contain some rows, but then another user could perform in the same time the WS, that should fill the table with another values, how is works?
Temporal tables are saved for each users or how it works, for my case?
Thanks in advance
Both temp tables are based on scope. When variable/buffer goes out of scope tables are dropped. So each user or WS call uses its own table.
You can find specs here:
https://msdn.microsoft.com/en-us/library/gg845661.aspx
https://msdn.microsoft.com/en-us/library/bb314749.aspx
I have a Social Graph assignment, and I have a pretty good idea of what I want to do, I just want to know if I'm on the right track, and any hints you guys can provide.
Anyway, fairly simple implementation (I found a very complex one here - How to model social graph in Java, but I think it's far more than what I actually need). Essentially my idea is to make a "User" object and a hashmap to keep everything in. A User object will have 4 data structures within it - name (string), student (boolean), school (string), and friends (integer array).
Each user will be added to the hashmap, and thus given a unique key. When a friendship is to be made, say between A and B, I go to the user A in the hashmap and ad the key for user B into A's friends array, and vice versa. That way I can keep track of everyone and who they're friends with.
Does this make sense? It works out in my head, but I feel like I'm missing something in the implementation that will make this not work as well as I think it should.
The answer to this will depend on the requirements and what you want to do with your social graph (especially on whether you want to persist the data or not).
If you are using a hashmap as your user store, then I assume you have a separate class that is generating your ids (or you have a UserStore class that wraps the hashmap and generates them)? If you are not deleting users, then you could suffice to have an ArrayList as you store, with the index being the user key.
When it comes to the users themselves, you could hold their friends in a List, but that may complicate your delete user code slightly (assuming you have that functionality).
UPDATE:
If you want to do analysis, then you may get some benefit from storing a User's friends as a Set<"UserKey"> instead of as an array (but depends on how you plan to do your analysis). You would still need a counter class (or master UserStore class that assigns the ids).
I would add some form of "primary key" to the User object, a number that might be sintetic (taking the next number from a global integer counter). This way, you can avoid the situation of generating a hashCode() value from the other User's data, and then you can avoid collisions inside the Map.
Well, it can work.
The only thing you're missing for sure, is that adding a User to a HashMap does not "give" it a key. The key should be created by you somehow. You can choose the user's first name, last name or to generate an incremental id. You add the User to the HashMap by giving it that key and the User as the value. You'll have to use that key each time you want to retrieve that User from the HashMap.
In your case, if first and last name are unique, use firstName + " " + lastName as the key.
There are many other recommendations that widely depend on the expected usages of the model. So, I don't see a reason to get into all of that.
Using ASP.NET, I'm building an admin tool that requires a function to import a list of email addresses. Upon uploading the file, I want to check for existing records for any of the email addresses supplied. For non-existing email addresses, I would create them using my DAO.
Basically I want to:
Receive list of emails
Retrieve data for existing emails
Create data for new emails in db
Return full data for all emails in list.
Since I want to know which of the emails exist up front, my first thought was to query the table for all records WHERE Email IN ('Email001FromFile', 'Email002FromFile', 'etc...') but the list could potentially contain thousands of email addresses, and I'm not certain supplying that many email addresses to the IN operator would be a good idea.
I also thought about looping through the list and checking for a record for each email, but that would potentially generate far too many queries.
My next thought was to generate a temp table to hold the list and modify the IN clause to use the temp table, rather than an explicit list of items, but that would require I execute SQL or a stored procedure directly, which I'm not inclined to do since I'm using NHibernate to access my DB.
Though I am using ASP.NET (C#) and NHibernate, and any answers specific to that would be helpful, I'm really just looking for general ideas on how to handle this scenario.
If loading the existing e-mails into memory is not an option I would maybe go for some kind of batch approach. Go for the IN-query you mention, but do it only for n emails at time. You could eiter hardcode n to a certain value or you could let it be a function of the total number of new e-mails.
I'm not sure whether this approach really is faster than to perform one single IN-query (someone with more db-skills than me would have to answer that), but that would allow you to indicate some kind of loading status to the user.
Are you doing anything with the emails that are duplicates?
You could put a UNIQUE constraint on your table to only allow an email address to be entered once - then catch the exception SQL will throw when you attempt to insert a duplicate.