My Class in parse is called "MyClass" and this one has several objects like
| ObjectId | Names | owners | users | (owners is a pointer of another class)
I want to do a query that gives me all of the names in my object "Names" that belong to the owner but, when I do this query i get this:
com.parse.ParseObject#41828fe0
com.parse.ParseObject#41829fdd
com.parse.ParseObject#4182aa28
my code is this
final ParseQuery query = new ParseQuery("MyClass");
query.whereEqualTo("owners", ParseUser.getCurrentUser());
query.findInBackground(new FindCallback() {
public void done( List<ParseObject> MyList, ParseException e) {
if (e == null) {
adapter = new ArrayAdapter<ParseObject>(MyActivity.this, android.R.layout.simple_list_item_1, MyList);
listDev.setAdapter(adapter);
}else{
//error
}
please help me how to do that query that gives me all of name that belong to the owner.
EDIT
I found a solution and is something like this.
ParseQuery<ParseObject> query = ParseQuery.getQuery("MyClass");
ParseUser user = ParseUser.getCurrentUser();
query.whereEqualTo("owners", user);
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, com.parse.ParseException e) {
if (e == null) {
for (ParseObject parseObject : objects){
String task;
task= parseObject.get("owners").toString();
adapter.add(task);
adapter.notifyDataSetChanged();
}
} else {
// Something went wrong.
Toast.makeText(getActivity(),"Error: " + e.getMessage().toString(),Toast.LENGTH_SHORT).show();
}
}
});
Your real problem here is your ArrayAdapter. You would need a custom adapter if you want to use Parse objects as your data type. The built in adapter doesn't know how to use Parse objects and is outputting the object as a string for you. Instead you should do something like
arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, MyNamesList);
Where MyNamesList is of type String.
It's hard to help on your query without more information but you are getting Parse objects back, you just need to get the name out of them with something like
MyList.get(i).getString("name");
somewhere outside the query method
private ArrayList<YourObjectType> list;
public void done(List<ParseObject> objects, ParseException e) {
if (objects == null || objects.size() == 0) {
return; //no objects
}
list = new ArrayList<YourObjectType>();
for (int i = 0; i < objects.size(); i++) {
YourObjectType myObject = new YourObjectType();
ParseObject object = objects.get(i);
myObject.objectId = object.getObjectId();
myObject.names = object.get("Names");
myObject.owners = object.get("owners");
myObject.users = object.get("users");
list.add(myObject);
}
adapter = new ArrayAdapter<YourObjectType>(MyActivity.this,android.R.layout.simple_list_item_1, MyList);
listDev.setAdapter(adapter);
}
now set the list to your adapter
your adapter should be able to handle objects of your type, so i think you need to create a custom adapter, the one provided by the android sdk, won't do here
The solution is pretty easy, since you are getting com.parse.whatever, all u need to do is ParseUser user = ParseUser.getCurrentUser();
Then query.whereequalto("owner", user.getUsername());
The problem was, u where querying for currentUser instead of usernames.
Related
I want to show all object from every Relation in following Query. But it still empty. I tried with the this Code, but it did not work. I hope someone can help me. Thanks in advance
mData = new ArrayList<>();
ParseQuery<ParseObject> receiver = ParseQuery.getQuery("Group");
receiver.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> feed, ParseException e) {
if (e == null) {
mData = feed;
for (int i = 0; i < mData.size(); i++) {
ParseRelation<ParseObject> relation = mData.get(i).getRelation("Data");
ParseQuery<ParseObject> query = relation.getQuery();
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
rData = objects;
Log.e("APP", String.valueOf(rData.size()));
Log.d("APP", "mData" + mData.size());
if (mSwipeStack.getAdapter() == null) {
mAdapter = new SwipeAdapter(getContext(), rData);
mSwipeStack.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
Log.d("mAdapter", "Loaded");
}
}, 4000);
//mSwipeStack.setListener(getActivity());
Log.i("APP", "We found messages!");
}
}
});
}
}
}
});
Sorry for my bad english :)
I suggest you to use pointers and not relations (in your case) and i will explain why:
It is not best practice to run findInBackground in a loop because if your dataset (mData) size will be large you will execute mData.size calls to the server and this is not a best practice and also not scalable. I suggest you to use Pointer Arrays (you can read more about it here)
by using arrays you will need only one service call to get all the data to your client (this way your solution will be more scalable and much more simple)
So your new solution (if you will decide to go with it of course :)) will be the following:
Group collection
Data collection
One to many from Group to collection (just read in docs how it can be done)
And then your code will look like the following:
EDIT1 - use getList
ParseQuery<ParseObject> receiver = ParseQuery.getQuery("Group");
reciever.include("data");
receiver.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> feed, ParseException e) {
// in here you can access all the data which under group in the following way:
for (int i=0;i < feed.size();i++){
ParseObject obj = feed.get(i);
// here you have all the data collection
List<ParseObject> dataItems = obj.getList("data");
// now you can loop on dataItems
}
}
});
Please note there is a chance that my code is not 100% accurate but i hope you got the idea.
Good Luck :)
I am having some trouble getting some data from my Parse table/object with a query. I am trying to simply make a query which looks for the current Parse User's objectID in the "sender" column. When that result is returned, I want to extract the receiver's objectID from the "receiver" column associated with the user that I searched for. I keep getting 0 results, even though I know the data is there. Here is my code:
private List<String> potentialRelationQuery() {
mPotentialRelations = new ArrayList<>();
String currentUserId = mCurrentUser.getObjectId();
ParseQuery<ParseObject> query3 = ParseQuery.getQuery("PotentialRelation");
query3.whereEqualTo("sender", currentUserId);
query3.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> parseObjects, ParseException e) {
if (e == null) {
if (parseObjects.size() > 0) {
for (int i = 0; i < parseObjects.size(); i++) {
ParseUser receiver = (ParseUser) parseObjects.get(i).get("receiver");
String receiverId = receiver.getObjectId();
mPotentialRelations.add(receiverId);
}
}
} else {
Log.d("MyApp", "No matching objects returned from request");
}
}
});
return mPotentialRelations;
}
Since findInBackground is an asynchronous call to Parse isn't it possible that mPotentialRelations returns empty because the findInBackground query hasn't yet completed before the potentialRelationQuery method returns? I know I've had issues with this. Since you can't return data from an inner class (i.e. in the done method of FindCallback), writing this kind of query method has never really worked consistently for me.
I've built an application that uses Parse. My application allows users to register, login and then post to a parse cloud database.
I have two Parse classes, one called User and one called Posts. User is made up of ObjectId, username and password, and Posts is made up of ObjectId, text and user. Of which user is a pointer to ObjectId within the User class.
I've created a method in my app called getData() which contains a ParseQuery, this queries the Posts class, selects the text field and includes the user field. The query then retrieves the data into a List and then loops through each row of the List, collecting the String from the text field and then adds it into a ListView on the UI using postList.add(textList.get(i).getString("text")); each time the program goes through the loop.Within the loop is another query, which queries the User class, selects the objectId field, I then add a constraint to the query to tell it to only retrieve data where the objectId field is equal to the user field within the Posts class(I think).
ParseQuery<ParseObject> queryUser = ParseQuery.getQuery("User");
queryUser.selectKeys(Arrays.asList("objectId"));
queryUser.whereEqualTo("objectId", textList.get(i).getString("user"));
Next I want to take the collected username data that the query retrieved, put it into a String and display it on screen in a toast. So basically the getData() method should collect all of the strings from the text field and the username of the user that posted it. The problem is that I'm unsure if i'm trying to go about this in the right way. My app throws an error when this piece of code is executed so I'm obviously doing something wrong.
java.lang.IllegalStateException: ParseObject has no data for this key. Call fetchIfNeeded() to get the data.
at com.parse.ParseObject.checkGetAccess(ParseObject.java:3235)
at com.parse.ParseObject.getString(ParseObject.java:2817)
at com.text.parse.MainActivity$3.done(MainActivity.java:186)
Code at line 186 : queryUser.whereEqualTo("objectId", textList.get(i).getString("user"));
My questions are:
1. Am I trying to do this in the right way?
2. Why am I receiving this error?
Code for getData() method:
public void getData() {
final ArrayList<String> postList = new ArrayList<String>();
final ArrayAdapter<String> listAdapter = new ArrayAdapter<String>(this, R.layout.listview_row, postList);
final ParseQuery<ParseObject> queryPosts = ParseQuery.getQuery("Posts");
queryPosts.selectKeys(Arrays.asList("text"));
queryPosts.include("user");
queryPosts.addDescendingOrder("createdAt");
queryPosts.setLimit(20);
queryPosts.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> textList, ParseException e) {
if (e == null) {
//query successful
for (int i = 0; i < textList.size(); i++) {
postList.add(textList.get(i).getString("text"));
ParseQuery<ParseObject> queryUser = ParseQuery.getQuery("User");
queryUser.selectKeys(Arrays.asList("objectId"));
queryUser.whereEqualTo("objectId", textList.get(i).getString("user"));
queryUser.setLimit(20);
queryUser.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> userList, ParseException e) {
if (e == null) {
String s = userList.get(0).getString("username").toString();
Toast.makeText(MainActivity.this, s, Toast.LENGTH_LONG).show();
}
else {
//query error
Toast.makeText(MainActivity.this, "query error: " + e, Toast.LENGTH_LONG).show();
}
}
});
}
lvText.setAdapter(listAdapter);
} else {
//query error
Toast.makeText(MainActivity.this, "query error: " + e, Toast.LENGTH_LONG).show();
}
}
});
}
Sorry for the long question. Any help would be greatly appreciated, thanks.
UPDATE:For anyone stuck with a similar problem, here's how I got it to work:
public void getData() {
final ArrayList<String> postList = new ArrayList<String>();
final ArrayAdapter<String> listAdapter = new ArrayAdapter<String>(this, R.layout.listview_row, postList);
final ParseQuery<ParseObject> queryPosts = ParseQuery.getQuery("Posts");
queryPosts.include("user");
queryPosts.addDescendingOrder("createdAt");
queryPosts.setLimit(20);
queryPosts.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> textList, ParseException e) {
if (e == null) {
//query successful
for (int i = 0; i < textList.size(); i++) {
postList.add(textList.get(i).getString("text"));
ParseObject po1 = textList.get(i);
ParseObject po2 = po1.getParseObject("user");
String username = po2.getString("username");
Toast.makeText(MainActivity.this, username, Toast.LENGTH_SHORT).show();
}
lvText.setAdapter(listAdapter);
} else {
//query error
Toast.makeText(MainActivity.this, "query error: " + e, Toast.LENGTH_LONG).show();
}
}
});
}
You simply include the column in the class you are querying that holds a pointer to another class, that then gives you access to all of the columns of data within the second class.
This method as shown is doing nothing useful:
ParseQuery<ParseObject> queryUser = ParseQuery.getQuery("User");
queryUser.selectKeys(Arrays.asList("objectId"));
queryUser.whereEqualTo("objectId", textList.get(i).getString("user"));
The selectKeys statement is telling it to only return the contents of the objectId column, which you are passing in to the whereEqualTo statement as a parameter... seems silly to run a query to get a value you already have!?. I would not user selectKeys until you think you need to optimise your queries. The only use this query would have is to let you know if the objectId is valid, since the query will return null if it isn't a valid objectId for a User.
I'm hoping that you want to get more information about the user, so if you remove selectKeys then the other columns will be returned.
The fact that fetchIfNeeded is throwing an exception on due to this line:
queryUser.whereEqualTo("objectId", textList.get(i).getString("user"));
That suggests that textList.get(i).getString("user") is not returning an objectId for a user. If that is instead returning a username as suggested by some of your other comments (not sure here), then you need to change that line of code to read:
queryUser.whereEqualTo("username", textList.get(i).getString("user"));
If there are some other questions you have, you'll need to be a bit more precise in your questions as it isn't really clear what you're asking at the moment.
I am trying to retrieve 2 values from my Cloud Code function. A List of ParseUser and a List of ParseObject.
This is a snippet of the Cloud Code.
...
var finalResult = {"users":users,"groups":groups};
//users is an array of Parse.User
//groups is an array of Parse.Object
response.success(finalResult);
This is the call from the client.
ParseCloud.callFunctionInBackground("serviceUpdate", new HashMap<String, Object>(),new FunctionCallback<HashMap<String, List<ParseObject>>>() {
public void done(HashMap<String, List<ParseObject>> result, ParseException e) {
if (e == null) {
List<ParseObject> users = result.get("users");
List<ParseObject> groups = result.get("groups");
As you can see, users is now a ParseObject. How can I obtain the ParseUser? Any suggestion is appreciated.
Can't you use casting, as follows:
ParseCloud.callFunctionInBackground("serviceUpdate", new HashMap<String, Object>(),new FunctionCallback<HashMap<String, List<ParseObject>>>() {
public void done(HashMap<String, List<Object>> result, ParseException e) {
if (e == null) {
List<ParseUser> users = result.get("users");
List<ParseObject> groups = result.get("groups");
To obtain as results Parse User you have to query the "User" table with this specific query https://parse.com/docs/android/guide#users-querying.
So you can retrieve the unique id from your posted query (it is a string) and then use that as filter for the new query.
I am new to parse data from parse.com.I am trying to update a column.The column in parse table is of array type.I am trying to add a value in array.For Example :
it is showing in data browser like this:
["Ado", "Wassja", "Cristi_3"]
And I want to add "ABC" value in this array programmatically like this:
["Ado", "Wassja", "Cristi_3","ABC"]
I have searched for this and got to know that first I need to fetch all the data of that particular row which I have to update ,then put the data in array I have fetch successfully the data for that particular row like this:
ParseQuery<ParseObject> query = ParseQuery.getQuery("UserMaster");
query.whereEqualTo("userName",str_uname2);
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> userList, ParseException e) {
dlg.dismiss();
if (e == null) {
if (userList.size()>0) {
for (int i = 0; i < userList.size(); i++) {
ParseObject p = userList.get(i);
str_dbpassword = p.getString("password");
String email = p.getString("email");
List<ParseObject> mfollowers = p.getList("followers");
List<ParseObject> mfollowing = p.getList("following");
ParseFile pp = (ParseFile)p.get("photo");
str_dbuname = p.getString("userName");
}
Log.d("password", "Retrieved " +str_dbpassword +"<uname>"+str_dbuname);
}
}
else {
Alert.alertOneBtn(LoginActivity.this,"Something went wrong!");
}
}
});
Now I have to update data in
List<ParseObject> mfollowers = p.getList("followers");
And
List<ParseObject> mfollowing = p.getList("following");
I don't know how to do this.Please help me.Your small clue will be very helpful.
Per the docs: http://parse.com/docs/android/api/com/parse/ParseObject.html
You can use add, addUnique, addAll, or addAllUnique to add elements to an array on a Parse Object:
someParseObject.add("arrayColumn", "ABC");
someParseObject.saveEventually();
To expand on Fosco's answer:
ParseObject parseObject = new ParseObject("YOURCLASS");
String[] stringArray = ["Ado", "Wassja", "Cristi_3"];
List<String> stringArrayList = new ArrayList(Arrays.asList(stringArray));
if (stringArray != null)parseObject.addAll("YOURCOLUMN", stringArrayList);
Make sure that the security settings for YOURCLASS enable you to create columns automatically or that you have the correct types set for your columns.
I hope that completes Fosco's answer.