I am trying to figure out how I execute my database operations efficiently and effectively. I have it so that when a user logs in, I use the Facebook API and grab details regarding the user's friends and place them into my database. This is done in a method called createFriend. However, if I login a second time, I get an error because every friend has a unique user id. Therefore, if I log in the second time, my code calls the createFriend method yet again and tries to insert the same friend that was already inserted the first time I logged in, and I get a unique column violation.
As a result, I don't know when I should call the createFriend method. I thought of 2 solutions to fixing my problem:
I looked at this link to see if I could check each row and if that row exists, only then I do the insert. I found: SQLiteDatabase: Insert only if the value does not exist (not via raw SQL command). It just doesn't seem very efficient to check every single time I want to insert a friend, to see if the row exists, and if not, I don't insert, otherwise I do. I have to do this select statement for every friend the user has.
The other method I was thinking of was this: I can call the Facebook API and check if the number of friends returned from the Facebook API is equal to the number of rows in my local database. If so, I skip calling createFriend all together. If not, I can just remove the entire database and reinsert all the friends again. However, this doesn't seem to work well because there is the chance that the Facebook API can keep returning the same number of friends as are in my database, BUT those friends returned could be different people than what the database has. Therefore, the database won't update because the number of friends is still the same, but I would want it to update because I would like to insert those potential new friends into the database.
Can anyone please point me in the right direction on where I can solve this problem? Thank you!
You can update on duplicate key.
Have a look at this for reference,
SQLite UPSERT - ON DUPLICATE KEY UPDATE
It just doesn't seem very efficient to check every single time I want to insert a friend, to see if the row exists
You are jumping to conclusions.
Guesses are likely to be wrong; you do not know how fast a query is until you have actually measured it.
And when you have a UNIQUE constraint, the database searches for a matching row anyway, so there will not be any additional I/O.
In any case, make your algorithm correct before thinking about optimizing it.
And if you want to ignore friends that already exist in the database, just use INSERT OR IGNORE.
Related
I have been looking for this quite some time now and i haven't found any answer related to my problem, so before you tag my question duplicate, at least read it first.
First i have just started firebase and only know basic things about it, i am trying to make a simple single user (1 to 1) chat app.
I want to get the number of users logged in in the database.
I have a child to the root of my database called users which have the list of the users who have logged in.
I know about the datashot.getchildrencount() but that works when some update/event happens, but i want it to give me the number of users whenever i want, not only on some event (For example in messenger number of current active users are shown continuously,i dont want active user tho, i just want total logged in users).
I thought of the another way to make a child called NumberofUsers so i store number of users there but then firebase dont allow to getvalue of the child,only set value (it does allow to get value but only on some event). Any idea what should i do?
UPDATE
i thought of another way to do this, though its not working at the moment but i think solving it is easier than thinking of another method to solve my original problem.
so I made one more child of NumberofUsers with key "02" and random value. now everytime i want data of "01" i change the value "02" after enabling the addChildEventListener for "NumberofUsers". Code that does this. Error its giving me. .new database.
Apparently I cant access child data using datasnapshot, any solution?
Any idea how to solve either of this?
Thank you.
Unfortunately, there is no way in which you can read data from a Firebase Database without attaching a listener. Regarding Firebase, everything it's about listeners. In your case, i think you want a callback to be called once and then immediately removed. If so, i recomand you using addListenerForSingleValueEvent() method to simplify this scenario. It triggers once and then does not trigger again.
This is useful for data that only needs to be loaded once and isn't expected to change frequently or require active listening.
Hope it helps.
I know this question a lot here, But I don`t know about this. This is about chat app.
When message get stored into the firebase database. It would become bigger and bigger as time goes by, I want to delete it. and when should I delete this? I just want to left just only last 10 data. It means if I out the app and again go in, It appears only last 10 sentence and I know about the function limitToFirst and limitToLast (but this is not the delete thing.)
If I pay firebase server, you know, if database's data is large It will be more expensive. but I just want to leave just last 10 sentences at least.
when they did come back then they can see the last 10sentence and want to delete except for this. how do I do this?
I saw the answer using the date, but I don`t want that. Is that only answer? If I must do that when I get to delete them? When do I invoke the delete function?
I know how to do that almost, but when? If in the app, there are so many friends and I open the chat screen to chat my friend. That time should I delete them using remove function? How am I saving this for server payment?
I don`t want cost a lot. and I want them to be clear, not dirty in my Firebase database console. so want to delete them. Which is the I have to do? Which time is the best time that I should delete them? When open it ? or when close it ? or when users stop the my app.
You can achieve this in a very simple way. You can use the getChildrenCount() method on the node in which you hold the messages to see the exact number of messages. If you are using as an identifier the random key generated by the push() method, it's very easy to delete the extra messages. Because the records are by default order by date, you can easily query your database using limitToLast(limit) method and than delete the messages like this:
yourRef.child("messages").child(messageId).removeValue();
Another way to achieve this is to use Cloud Functions for Firebase.
Hope it helps.
you can use firebase functions to delete old data when new ones added to the database that is the best time, you can keep the last 100 messages or less.
I'm wondering whether there's a way to force a table to have only one record. My use case is that I only allow one user to log into the app at a time, and overwrite that only record (if there's one).
I know it defeats the point of having a database if only 1 item is allowed. But I've got other tables with normal behaviour (multiple rows), only the logged-in-user table needs this, and I don't want to use another persisting scheme just for this case.
Any tip how to achieve this? Thanks
I'm wondering whether there's a way to force a table to have only one record.
There is no way from a database perspective or via ORMLite but there are many ways that you can implement this in your own code.
One way that comes to mind is to have a LoggedIn table with a single row in it. You then can do some sort of conditional update of the row in the table.
Something like (in pseudo code):
use the UpdateBuilder to make a conditional update:
like: UPDATE LoggedIn SET user = my-user-name WHERE user IS NULL
refresh the logged-in entity
if my-user-name.equals(loggedIn.getUser()) then
I'm logged in and can continue
else
I can't login because someone beat me to it.
One of the tricks of this method is that you need to set the user back to null later when the user is logged out. If the application crashes then you will somehow need to reset. Maybe some sort of login timeout? You mention Android so maybe you could clear the logged-in table when you start unless this is a remote database.
Hopefully this gives you some ideas.
Based on the parse AnyWall demo for android, and app that shows messages at certain locations, I made a similar app for food, essentially showing what the user is eating. I can successfully post to the Parse table and show the location of the user and what they are eating on a map. However, what I would like to do is when the user creates a new post, their old post gets deleted and their new post is added to the table. Essentially, any given user can only have 1 post on a map at a time. I have seen the deleteInBackground method, but cannot seem to find the table to specify and a specific username to specify. How would I go about doing this on Android? Thanks.
You can use username as column and you can write before save method on Parse cloud for your table. So when you want add a new record your before save method can detect the duplicate entry on your table and delete it. I hope I understand your question.
Regards.
I am creating an app in which users can make posts and other users can like and comment over these posts.To achieve this facility i am using tables likes POSTS, LIKES, COMMENTS.(I am using parse.com database to store these table).
POSTS have fields like postId, content, userWhoMadeThePost, dateOfPosting
LIKES contains filelds as id, postOnWhichLikeWasMade (foreign key to POSTS(postId)), userWhoLiked, dateofLike
COMMENTS have id, content, postOnWhichCommentWasMade(foreign key to POSTS(postId)), userWhoCommented, dateOfComment
I want to retrieve most popular posts (posts with most no of likes and comments).
First way to do this is count no of post and likes for each post each time whenever a request is made for popular posts but this can become very time consuming if
there are millions of posts.
Other way to do this one way is to include 'noOfLikes' and 'noOfComments' in POSTS table, so in order to get popular posts I will have to access only post table, but the problem with this approach is whenever a user makes a comment over a post then I will have to increment 'noOfComments' in POSTS table as well as make a entry in COMMENTS table, problem starts when the increment is successfully made to POST table and before making change to the COMMENTS table connection is lost. In that case POST and COMMENTS table would be showing wrong data.
How to do this?
This would be simple, if you had control over the database, but doing this with Parse means that you have two main problems (one of which you already mentioned):
As far as I can tell, Parse does not allow grouping in queries. That means that (with your schema) it's actually impossible to get the most liked/commented posts without retrieving all of them. This is because you can't actually dynamically add a new column with the number of likes/comments like you would in a standard SQL query (using JOIN and GROUP BY).
You can't update more than one object within one transaction, so there is the possibility that a user could add a comment but the number of comments in the post object would not change.
That being said I think (at least if you insist on using parse) you must add the 'noOfLikes' and 'noOfComments' columns to the Post object. Not only does it provide the only viable solution for retrieving N top posts (without getting all of them), but the actual risk of inconsistencies is pretty low in my opinion. You can always catch network (or other) exceptions and temporarely store the update requests locally and retry them later.