Android: ParseQueryAdapter to query multiple classes - android

This is my first question asked and hopefully someone can help me. I have looked around and nothing on this subject has helped me in my situation yet which is why I resorted to posting a request for help.
I have a parse.com database setup with the following Classes:
Users, Followers, and Items.
Followers contains two columns follower and following to keep track of which user is following which user.
Items contains an author column which is a pointer to a User object.
My goal is to make a query for a ParseQueryAdapter that will return Items objects. The path that I have to Items right now is to query the Followers class to get a list of users that the current user is following. Then use those user objects as pointers query the Items class for items the followed user has created.
Here is a diagram:
Followers
follower following
------- ---------
UserA UserB
UserB UserC
UserB UserA
Items
author column1 column2
------ ------- -------
UserA foo bar
UserA foo2 bar2
UserB blah blah
UserC blah blah
Based on the above database structure let's assume that currentUser is UserB. If UserB queries the Follower table he will retrieve his follower list (UserC and UserA) and then I would like to query to go out and retrieve all of the Items created by those that UserB follows (which should return 3 results based on the above structure). Based on my limited understanding of how parse.com works here is what I have tried:
public class ItemListItemAdapter extends ParseQueryAdapter<ParseObject>{
public ItemListItemAdapter(Context context) {
super(context, new ParseQueryAdapter.QueryFactory<ParseObject>() {
public ParseQuery<ParseObject> create() {
ParseUser currentUser = ParseUser.getCurrentUser();
ParseQuery<ParseObject> followerQuery = new ParseQuery("Followers");
followerQuery.whereEqualTo("follower", currentUser);
ParseQuery<ParseObject> itemQuery = new ParseQuery("Items");
itemQuery.whereMatchesQuery("author", followerQuery);
return itemQuery;
}
});
}
As I understand it I am first creating a query that will get the followers that currentUser is following. Then I should have a list of User objects that can be used to query the Items class where the User object matches the followers so that I can populate my ListView item with the right data from that Item object but this query returns zero results.
So either I am modeling everything wrong or I am misunderstanding how relationships work. Any help would be greatly appreciated.
If I remove the itemQuery and just return the followerQuery then it works - the problem is with the inner query when I try to combine the two (or it could be me complicating my life with the data structure in the database so I'm also open to suggestions on restructuring).
Thanks for your help in advance!

The answer was to not use whereMatchesQuery() but whereMatchesKeyInQuery() instead.
here is an example using whereMatchesKeyInQuery() (that is not necessarily specific to this question but demonstrating the use of whereMatchesKeyInQuery by request in the comments):
ParseQuery followerQuery = ParseQuery.getQuery("Followers");
followerQuery.whereEqualTo("following", ParseUser.getCurrentUser());
userQuery.whereMatchesKeyInQuery("objectId", "followerId", followerQuery);
So the parameters would be:
query1.whereMatchesKeyInQuery("key_value_in_query1", "key_value_to_match_in_query2", query2);

Related

Android's Firestore to join 2 collections into a recycler view

I have a users collection with uId, name, photo
I have a visits collection with uId, userId, location
I have a recyclerview in which I want to show the location with the user name and photo
Can I use the reference field type? If so, how will Firestore know to link visits.userId == users.uId ?
Maybe I first need to query all the visits and then query the relevant user but 2 things:
It means querying a lot of times.
I didn't understand how to collect the joined collection into the adapter, which is based on one query?
Please advice
Thanks
current code
visitsList = db.collection("visitsList");
Query query = visitsList.whereEqualTo("userId",prefs.getString("id","")).orderBy("visitDate", Query.Direction.ASCENDING);
FirestoreRecyclerOptions<AVisit> options = new FirestoreRecyclerOptions.Builder<AVisit>().setQuery(query, AVisit.class).build();
adapter = new VisitsListAdapter(options, VisitsListActivity.this);
RecyclerView rv = findViewById(R.id.rvVisitsList);
rv.setHasFixedSize(true);
rv.setLayoutManager(new LinearLayoutManager(this));
rv.setAdapter(adapter);
The code is a simple query from the collection, not sure how to get the name and photo from the userId field in that collection.
Can I use the reference field type?
Yes, you can use a reference field.
If so, how will Firestore know to link visits.userId == users.uId ?
Firestore results always comes from a single collection (at the moment). It does not automatically join the document from the users collection when you're reading from the visits collection. You will have to do this yourself.
That indeed means you'll be executing multiple reads, but it's often not nearly as slow as you may think. See Google Firestore - how to get document by multiple ids in one round trip?
Update: To show data from the user profile in a list of visits, there are two main options:
load the additional user document in populateView or with a custom parseSnapshot implementation.
duplicate the relevant user data in the visits collection (which is quite normal in NoSQL databases). Also see Alex' answer here: indexed query with FirestoreRecyclerAdapter.

How to do a relation in Parse Android?

I have some problems with relations in Parse, I don't know why I can't do a relation fine.
my app: a user can create posts, and look posts from other users, a user can add a favorite post to a list, and then see the list of their favorites. I think I need relations many to many for do it.
I have a button "add favorite" , a class "favorites" and a class "posts"
favorites has userId(current user) , and post(favorite post)
posts has namepost,description,category
I tried this.
ParseObject fav = ParseObject.create("favorites");
fav.put("userid",ParseUser.getCurrentUser());
ParseRelation relation = posts.getRelation("objectId");
fav.put("post",relation);
fav.saveInBackground();
But never saves . I also I tried to create a column in Parse "User" class but never works. Some suggestions?. Thanks.
Ok for answer my own question. I created a class Favorites with two columns, user, post
user: ParseUser.getCurrentUser()
post : obj.getobjectId
If I want to retrieve the favorites, first I search for them in a query and save it in a list.

Android parse.com I can't get second user from data base

I have two tables in data base. One is user ad the second is transaction that have pointer to the first user, pointer to the second user and int. When I try make and display list I have error. I want to display all rows that CurrentUser is in first column:
ParseUser cu = ParseUser.getCurrentUser();
query.whereEqualTo("first", cu);
and list it with firstUser, secondUser and int:
from Adapter:
ParseObject taskObject = mTask.get(position);
ParseUser first = taskObject.getParseUser("first");
holder.firsthp.setText(first.getUsername());
ParseUser second = taskObject.getParseUser("second");
holder.secondhp.setText(second.getUsername()); //this line make error
int ile = taskObject.getInt("ile");
holder.taskhp.setText(Integer.toString(ile));
return convertView;
This is how transakcja table looks: http://i.stack.imgur.com/yh83p.png
When I saving transaction (when transaction table is clear, don't have any records) and immediately read it works but when I logout and login it crashes.
And here is entire code for toDoActivity Task Adapter and hplayout:
I had problems with pasting code here so I pasted it on pastebin
http://pastebin.com/2wtQLJXE
I think I know the problem. When you are calling your query on the transaction table, the two User's are Pointers to ParseObjects, or ParseUsers in this case. You need to ensure that these objects are FETCHED as well by the ParseQuery in order to properly access their data. They are ParseObjects with data from another table, Parse does not automatically retrieve them so you must tell Parse to do so when you need that data.
Looking at ParseQuery documentation for Android we find the include method.
public ParseQuery include(String key)
Include nested ParseObjects for the provided key.
You can use dot notation to specify which fields in the included object that are also fetched.
You want to use this to include columns names to Pointers of ParseObjects so the query fetches them at the same time as fetching the rest of the data from the table, in this case your transaction table.
Add this:
ParseQuery<ParseObject> query = ParseQuery.getQuery("transakcja");
query.whereEqualTo("first", cu);
query.addDescendingOrder("createdAt");
query.include("first");
query.include("second");
The reason first is having no null issues, is it is the Pointer to the current ParseUser logged in, which doesn't need to be fetched as it's data is accessible. The second one is not fetched, therefore adding the include to the query SHOULD fix this :). Make sure to also include the column "first" because I'm sure your future ParseQuery's will not always be between the current user and non-current second user

How to make query for Many-to-Many Relation using Parse.com database?

I can't seem to figure out how to make a proper query for a many-to-many relation. I have two classes:
_User (standard)
Group
A user can be a member of multiple groups, and a group can have multiple users.
In the User class i created a relation to the Group class: |_groups (group)|.
I want to make a query to get all the groups where the current (logged-in) user is a member of. I already read the Developer Guide, but i just cant seem to figure out how to do it.
Thanks in advance!
> edit:
I figured it out:
ParseObject current = ParseUser.getCurrentUser(); //get current user
ParseRelation relation = current.getRelation("groups"); //select the relation
ParseQuery query = relation.getQuery(); //get all relations

How to retrieve data from multiple Parse.com Tables/Classes

I have two tables (Classes):
StudentInformation: with columns RollNumber, address, name, school
StudentMarks : with columns RollNumber, Marks1, Marks2, Marks3
I've been able to save the data from a single form into these two simultaneously, but not getting a clue on how to put a query while retrieving into a listview or any other view something like
'return rows (from both tables together) where roll number = 1234' / 'return rows (from both tables together) where Marks2 > 50'
I'm using Parse.com backend for Android
Kindly help
Thanks
First, the UI aspect of showing in a ListView is provided by ParseQueryAdapter. https://parse.com/docs/android_guide#ui-queryadapter
Regarding the query, I do not think you can join tables in the way you want. Instead, you could create a pointer in StudentMarks to StudentInformation.
Then you can query something like:
ParseQuery<ParseObject> query = ParseQuery.getQuery("StudentMarks");
query.include('studentInformation'); // include the pointer to get StudentInformation
query.whereEqualTo("RollNumber", 1234);
query.whereGreaterThan("Marks2", 50);
... // perform query
In the results StudentInformation will be available like this:
List<ParseObject> objects; // the result from the query
ParseObject studentMark = objects.get(0); // example using first object
ParseObject studentInformation = studentMark.get("studentInformation");
String studentName = studentInformation.get("name");
String studentAddress = studentInformation.get("address");
... // etc
Alternatively you could also store a Relation of StudentMarks on StudentInformation, just to let you know that this is also an option, though I do not feel like it fits your current need as well as the solution presented above.

Categories

Resources