Parse relational data queries - android

I'm new to Parse.com and was having trouble designing the structure of my database, and how to retrieve the desired data.
In the database, each user (primary identifier as email) has a list of friends and a status boolean. The friend list contains the email of other users in the database. I need to get the status boolean for each of the friends in a particular users list, and preferably in a single query to the server.
What would be a good way to design our structure and retrieve this data. Currently, I made two data classes (tables), one containing each user with their boolean status, and another containing each user and their list of friends. Firstly I was not sure if this structure is the correct way to go. Secondly, I don't know how to retrieve the status boolean for each user in a single users friend list.
Edit I actually discovered the relation column type just yesterday, but I was unable to figure out how to use it. 1) How do I link a Persona to a User in code? I understand I need to use ObjectID here, but how?
2) How do I add other Personae (friends) to a relation of a single Persona (the user). I was unable to populate this relation column. I understand query can be used on the relation column, but I couldn't reach that far ahead without populating the relation column.
3) In my query to the server, am I pulling the entire table? Lets say a user has 2 friends. Is there a way for me to fetch only the current user, and the two friends, or am I pulling the entire table, and then doing my filtering on it. I am concerned with the network being burdened if my table of users grows big.
Edit Well I couldn't figure out relational queries perfectly just yet, however, I found a good solution to my problem. Since the list of friends changes very rarely, I'll be maintaining this list offline, resulting in a single query to the server of pulling in the status of my friends. Along with this list, I may or may not also decide to pull in my own data and get an updated friend list. Thank you for your help though.

The way to model many-to-many relations in parse is with the relation column type. This is the best choice to describe how a user has many friends who are users. If this is a social-network-like app, another good bit of advice is to create a class -- distinct from the parse User -- that describes users' public personae.
This is so you can have the parse User class remain as the private, customer relationship between your app and a real person (there are built in security constraints here). This other table, say we call it Persona, can have a pointer-typed column to its user, keep such things as nickname, profile image, etc. and also keep your boolean status.
_User class - default stuff that comes standard with parse, plus anything pertaining to the customer relationship with your app.
Persona - pointer to _User table, boolean status, other public info, relation called "friends" relating this to other Persona.
So, given a logged in user and his/her currently selected persona (your choice whether users may have more than one personae), you can get friends' personae as follows (in pseudo code):
friendsRelation <- myPersona.friends
friendsQuery <- friendsRelation.query // query is a method on relation
run friendsQuery asynch, then the result will be allFriendsPersonae
for each persona in allFriendsPersonae
status <- persona.status
If you choose not to take the persona class advice, the "code" above is the same, just replace persona with user.
Edit - in response to question edit:
1) Link a persona the user by setting the persona's user column (pointer type) to the user object. To get that persona later, when you only have a user, query the persona table where "user" column equals user.
2) Relation implements an add() method. If you have a personaA, and want to add personaB as a friend, you getRelation("friends") on personaA, and send it add(personaB).
3) The query you get from a relation is a query only for members of that relation. So if personaA has two friends personaB and personaC, you'll get only B and C when you run personaA's friends query.

Related

How to Retrieve list of attributes from multiple Firebase nodes

My firebase DB looks like
Now I want to query the database such that I take all the users whose email id is in a query list.
For example in the above shown database structure, if I want to make a query such that find the users where username in ["allen20252482", "arne19712450"] which can give me two users.
Is it possible?
Currently I can query like https://xyz.firebaseio.com/users.json to get the complete user node data , But is it possible to filter like where I take only those users whose username is in the given query list?
I am using REST API endpoint to query the Firebase DB.
Any suggestion is very much appreciated
I suggest reading the documentation on filtering data. It sounds like you want to filter by a child key:
https://xyz.firebaseio.com/users.json?orderBy="username"&equalTo="abcdef"
You will only be able to specify one username at a time.

How to limite access to database based on ID

I have a team of three people with IDs 1-2-3
They report to me the number of articles they produced daily via an app with a database they upload on google drive or dropbox
so the table has three columns : DATE ID and Number
For example when person with ID=1 opens the app on his device only his inputs should be accessible (to view and edit)
But on my device i can see all the data
You can pass as parameter the user id in api Rest Call and make Sql request filtered by this ID, like that you get only result for this id
It would depend on how you write both the android code and the sql code.
From the sql perspective, in the editors side select all as usual and display in text view for those that he has to view and in editview the ones that he has to edit.
After insert the information into the database.
At the viewers side select as usual and display info in textview or any other widget of your choice.
I cannot actually say much because its really broad. Contact me if you need more specific solutions to your peculiar problem.

Should I query everytime I need something from Realm/SQlite?

I am using Realm/Sqllite for storing my user_id along with user names, and in my friends section I am showing all of my friends name along with other information where unique key is this user_id.
And in my friends section I am using recyclerview to show all of my friends data,
Now I was just wondering suppose I have 100-200 friends list now to show user name what I can do is query every time for user_id from Realm/Sqlite in order to show the name of the user. OR I can just query all user_id list parallely and store them in a HashMap and now for each user_id I can directly check in the hahsmap for getting user name.
I know second way will be faster but memory consuming also, and I checked the time taken by Realm/Sqlite for every query and it is around 1-2ms that's why I was thinking as it is not that slow I can directly query from Realm/Sqlite.
Do anyone of you use the other technique or just query every time you need to get something from database?

Database to use for storing profile information

I'm making an application for android which is used to store profile information of a user( FirstName, LastName, Email, Username, Password ). It will also store profile picture of the person. You can think of applications like WhatsApp, Viber Tango. There are many more like it.
In order to store and access this information easily and efficiently, how should these information be stored? I'm thinking about storing this information in Relational Database like MySql. I will have FN,LN,Email,Username, password and link to profile picture as columns of table. One more issue I had in mind is that if a user has say 100 friends, should I create a new table per user so that all his/her friends can be separate and accessed from single table or I should run some complex SQL query so that it returns list of friends of user?
Thanks a lot
I believe you are on the right track. MySQL is a fine choice for storing the data as long as it is on a server that can be accessed by your application.
You will need 2 tables: one to store all of the users and another to map the users friends.
Your users table will be pretty straight forward as you have already laid out. The other table (could be named something like user_friends) would have a column containing the id of the friend that made the request, another column containing the id of the friend that accepted the request, and any other x amount of columns you may need to contain information about the friendship. Any record without an id for the accepted friend can be displayed as a pending request.
I would make sure that there can only be one record containing a mapping of friends to prevent duplicates as well.

Looking up data with relational classes

I'm developing an Android app that uses the Parse.com online database, and i'm having some difficulty wrapping my head around the relationship between classes.
I have the following classes defined: User (default), PrivateInfo, Relationships.
The relationships class is a many-to-many class between users (users stored as pointers), and the PrivateInfo class contains information specific to a user (stored as a pointer) to be accessed only by said user or users present in a relationship. For example, if user A is in a relationship with user B, then A should be able to access this privateInfo.
I have an activity where the private info from all users is to be shown. How can I build a query that will fetch the privateInfo from all users in a relationship with the current user? I've seen the usage of innerqueries in the documentation and I think that's what I should be using, but the usage of ParseObjects is making this confusing to me, since i'd have to work with PrivateInfo and Relationship ParseObjects, and not a User parseObject, which is what is being pointed by the privateInfo class.
An easily missed part of the documentation is the Relations Guide that explains the different types of relationships in much more detail than I can in an answer.
In regards to doing a query for "userA", looking to get all PrivateInfo objects that are for users that have a Relationship record that points to "userA":
ParseQuery<ParseObject> relationQuery = ParseQuery.getQuery("Relationship");
relationQuery.whereEqualTo("user", userA);
ParseQuery<ParseObject> privateInfoQuery = ParseQuery.getQuery("PrivateInfo");
// find records where PrivateInfo.user == Relationship.relatedToUser
privateInfoQuery.whereMatchesKeyInQuery("user", "relatedToUser", relationQuery);
// if you also need the User so you can show info about them
privateInfoQuery.include("user");
This assumes your classes have the following columns:
PrivateInfo
user : Pointer<_User>
Relationship
user : Pointer<_User>
relatedToUser : Pointer<_User>
If you need to get Private info for reverse relationships too, it gets trickier. I can provide a sample OR query if needed.
You might want to look over the REST Api docs on ACL and on security..
Wnen you have User A in relation w/ B, you can UPD ACL READ on B's privateInfo , giving A read access.
Then you can just do an 'include=ClassPointedTO' on any query and the extra class ( private info will be inlined in response to flat query with the sensitive data ).
If u drop the relation you must keep info consistent by ALSO updating the ACL element to drop read on the dropped target of the dropped relation.
--EDIT--
So when the Privateinfo entry is created, you can grant ACL READ to the creating user if you want. Or you can grant ACL READ to a Role entry that the creating user is in. Or you can do both. You would also need ACL WRITE by the creating user.
After that, in any query by any user you would get the following on a direct Query on Privateinfo or on a query utilizing "?include=Privateinfo" ...
Users with READ ( either direct or via a Role which the user belongs to ) will have in the response those Privateinfo entries where they have READ.

Categories

Resources