Query both User object and Picture Object same time

Hi,
I am using Android Studio, Java and Parse.

I have two object (tables). One is the default “User” and another “Images” with a field storing username as it exist in “User” object.
I can query both separately perfectly. I can get all User details and I also can get all Images but separately in different queries.

I want to query both in the same query.

I want to get all from the “Images” object and I want to get the images and their corresponding fullname from the “User” object.

    ParseQuery<ParseObject> query = new ParseQuery("Images");
    ParseQuery<ParseUser> usersQuery = ParseUser.getQuery();

These command working perfect separately, how can I combine these to get the required results.

thanks

1 Like

I would adjust your database setup to fully utilise pointers.

Rather than setting the field on Images to username, instead, set it to ParseUser.getCurrentUser(). Then, you can include the keys for firstName and lastName on image.

This might be a bit confusing - but you will only need:

ParseQuery<ParseObject> query = new ParseQuery("Images");
query.include("user");
query.findInBackground(new FindCallback<ParseObject>() {
  public void done(List<ParseObject> images, ParseException e) {
    for (ParseObject image: images) {
      ParseObject user = image.getParseObject("user");
      Log.d("firstname", user.getString("firstName"));
    }
  }
});

To do this, I would add a beforeSave trigger on Images to enforce that images.user is the user that is saving the image.

Parse.Cloud.beforeSave('Images', ({user, object}) => {
  object.set("user", user);
  const acl = new Parse.ACL(user);
  acl.setPublicReadAccess(true);
  object.setACL(acl);
}, {
  requireUser: true
});

Then make sure “Images” queries only select firstName and lastName on user (we don’t want to expose the whole user payload.

Parse.Cloud.beforeFind('Images', ({query}) => {
  query._select = [];
  query.select('user.firstName', 'user.lastName');
}, {
  requireUser: true
});

And finally, make sure users can only query for themselves.

Parse.Cloud.beforeFind(Parse.User, ({user, query}) => {
  query.equalTo('objectId', user.id);
}, {
  requireUser: true
});
1 Like

Thanks dblythy for your reply.

As you said it is confusing and needs me to change my code. In the code below I am retrieving all fields from object “Images”. Inside it I would like to add the filed “mobile” from the “User” object. How can I do it. Please note I am creating an Android APP using Android Studio, Java and Parse.

ParseQuery<ParseObject> query  = new ParseQuery("Image");

query.include("User");

//Sort query by Ascending order as per created date
query.orderByAscending("createdAt");

query.findInBackground(new FindCallback<ParseObject>() {
    @Override
    public void done(List<ParseObject> objects, ParseException e) {

        if(objects.size() >0 && e == null){

            for(ParseObject object: objects){


                //ParseObject post1 = object.getParseObject("User");
                //object.getParseObject("User").getString("mobile");

                ParseFile file = (ParseFile) object.get("ImageFile");

                String user = object.getString("UserName");
                String type = object.getString("ImageType");
                String typeSub = object.getString("ImageTypeSub");
                String desc = object.getString("ImageDescription");

                Post post = new Post(user, type, typeSub, desc, file);
                allPostsList.add(post);

            }

            postAdapter.setPosts(allPostsList);
            postAdapter.notifyDataSetChanged();

        }else {

            Toast.makeText(getActivity(),"Showing Image Failed ......" 
             ,Toast.LENGTH_SHORT).show();
            //objectRetrievalFailed();
        }
    }
});

Yes sorry, the code that I sent was mostly for your cloud code. If you want to include “mobile”, you should add it to the beforeFind .select:

Parse.Cloud.beforeFind('Images', ({query}) => {
  query._select = [];
  query.select('user.firstName', 'user.lastName', 'user.mobile');
}, {
  requireUser: true
});

Note that this code isn’t required to make it work, it’s only to secure the users so that it’s restrictive.

As for your android code, to retrieve mobile, it should be as simple as:

ParseObject user = comment.getParseObject("User");
Log.d("mobile", user.getString("mobile"));