Is Parse relations/ pointers bi-directional? - android

This code sets up a Customer class, creates an object in it and assigns a pointer connecting the customer object to the ParseUser who created it.
ParseUser currentUser = ParseUser.getCurrentUser();
customer.put("CreatedBy", currentuser);
customer.saveInBackground;
ParseQuery<ParseObject> query = ParseQuery.getQuery("Customer");
query.whereEqualTo("CreatedBy", currentUser);
query.findInBackground(new FindCallback<ParseObject>()
The pointer is defined from Customer --> User but the query is against the customers. To go to the user I just need to check the value in the createdBy column but for the reverse an entire query is needed. Do I need to define a pointer in the other direction to optimize the query/ speed it up or does Parse enforce bidirectionality in its pointers and relations?
In a MongoDB afaik pointers must be defined in both directions for optimum query speeds. I will be using customer class much more and my app should work for 100k users+
My same doubt applies to the case of ParseRelations. I know I can use the 'include' key but is query both ways equally optimized?

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.

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

Android: parse.com query

I am using Parse as database.
I would like to ask if there are over 1000 items in the Data_db, where the username is unique.
Code:
ParseQuery<ParseObject> query = ParseQuery.getQuery("Data_db");
query.whereEqualTo("username", edittext_user.getText().toString());
query.setLimit(1);
Question:
While I know fetching over 1000 dataset we need to use the .setSkip(1000) function and performing looping, I would like to ask how about querying a specific user? Is it also limited to the first 1000 rows? and if yes, how could such user beyond 1000 could be queried?
Thanks!
You're going about this the wrong way, your query will be inefficient as you're looking 1 object when those constraints through an entire class, regardless of it being already found. It would be better to use getFirstInBackground(). Something like:
ParseQuery<ParseObject> query = ParseQuery.getQuery("Data_db");
query.whereEqualTo("username", edittext_user.getText().toString());
query.getFirstInBackground(...);
A maximum of 1000 objects can be returned to you through a single query, by using getFirstInBackground(), you're searching though the database, hence that limitation is not applied.

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

One to many relation on Parse.com

I have two classes on Parse.com : Image & User. In User class, I am saving 3 fields Name,Mobile-number & Occupation. In Image class I'm saving images.
I have to create one-to-many relation between these two classes so that I can fetch images with the corresponding mobile-number.
I have created a relation between User class and Image class on parse.com with a column named Mobile in User class. Not able to find how can I fetch the images with that particular mobile number with one-to-many relation. Please help as I have gone thru the documentation. Thanks in advance.
This is just the code to go about. You will have to think about organizing your classes thoughtfully. I am not sure how you intend to go but as far as coding is involved, the following should help.
First get the current user.
ParseUser currentUser = ParseUser.getCurrentUser();
Since, you have "mobile" column as the relation in the User table, get the relation first.
Like this.
ParseRelation<ParseObject> relation = currentUser
.getRelation("mobile");
Once you get the relation, get the query on the object who require. In your case, it is the Image Object.
ParseQuery<ParseObject> query = relation.getQuery("Image");
From here, you can customize your query. Eg:
query.getFirstInBackground(new GetCallback<ParseObject>() {
public void done(ParseObject, ParseException e) {
if(e == null)
//your code
//List<ParseFile> pFileList = (ArrayList<ParseFile>) object.get("images"); //something like this just to give an idea
}
});
Or if you have multiple objects, use
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> list, ParseException e) {
if (e == null) {
for (ParseObject object : list) {
ParseFile image = (ParseFile) object.get("images_column_name");
}
}
}
});
If an Image class only has one User it is related to, simply use a reference property. You could call it owner or user or whatever. You then just set this to the current user (or any other user).
Internally Parse will store just the ID of this object with some extra information to make this as a link to another class.
When you query you can simply use the current user (or any other user) to compare against that property. Again, Parse will internally just compare ID's, you don't have to think about it.
Look at the documentation here. See where it sets the parent property of the Comment to an instance of the Post? That's the sort of thing you want to do.
Using the mobile number to link is a bad idea, as if you change the number on a User then all the Image classes using that number are now orphaned, unless you write extra code to handle this.

Categories

Resources