I am having issued Retrieving objects from Parse.com. I plan to have a list of anywhere from 3 to 25 objects displayed, They will change daily. I will not know the ObjectID, or any of the content of the object. I followed this guide the best I could.
I wrote this code here to simplify what I am doing. It is throwing a null pointer exception in my .done.
UPDATED
Saving my object: //I am doing this successfully
ParseObject testObject = new ParseObject("TestObject");
testObject.put("TheColumn", "The name in the column");
testObject.saveInBackground();
Context context = getApplicationContext();
Toast toast = Toast.makeText(context, "Saved", Toast.LENGTH_LONG);
toast.show();
Retrieving my Object //Unsuccessfully....
ParseQuery<ParseObject> query = ParseQuery.getQuery("TestObject");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> parseObjects, com.parse.ParseException e) {
if (e==null){
Log.d("THE OBJECT", "" +parseObjects.size());
name = parseObjects.toString();
Log.d("THE QUERY ", "" + name);
} else {
Log.d("ERROR:", "" + e.getMessage());
}
}
});
In my logcat, I get my Log.d's to log. I get two; D/THE OBJECT: 1 and D/THE QUERY: [com.parse.ParseObject#XXXXXX] But if I try to set it to a TextView, I get a nullPointerException.
Why am I getting data returned like this? I feel I am following this guide closely.
The Reason for my nullpointer was that I was setting the text to a TextView in a different class on accident. Got my r.id's confused.
Related
I'm making a small application. trying to retrieve posts inserted, and then I want to retrieve only new inserted posts, and not retrieving all the posts again.
So do you have any idea on how to I can retrieve last items ( Since the list object retrieved)
Here my Query code :
public void getFeed(int limit, int skip){
ParseQuery<ParseObject> query = ParseQuery.getQuery("Feed");
query.setSkip(skip);
query.setLimit(limit);
query.setCachePolicy(ParseQuery.CachePolicy.CACHE_ELSE_NETWORK);
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> feedList, ParseException e) {
if (e == null) {
for (int i = 0; i < feedList.size(); i++) {
Post p = new Post(feedList.get(i).get("Text").toString());
mAdapter.addItem(p);
}
Log.d("result", "Here is it:" + feedList.size());
mRecyclerView.setAdapter(mAdapter);
} else {
Log.d("Feed", "Error: " + e.getMessage());
}
}
});
}
keep the last time you checked and then use that time to pull anything greater than the last time checked from the createdAt column or updatedAt column (if its possible for someone to update something you are pulling) of the object. then after your query is finished update that time to the current time.
you can store the viewed posts count and next time when retrieving the list set the count as parameter for skip:
query.setSkip(count);
How do you get a pointer to a parse object?
For example, my ParseUser has a column called "school", which is a pointer to a Parse class "School"
school Pointer<School>
I am able to get a ParseObject of type School, however, I don't know how to get a pointer to this School ParseObject so I can put it in the ParseUser's school field.
I saw similar posts to this one that said to create a parse object without data and give it the correct object ID:
ParseObject mySchoolPtr = ParseObject.createWithoutData("School", mySchoolObject.getObjectId());
currentUser.put("school", mySchoolPtr);
However, after running this code my Parse database for User just lists "(Undefined)" in the school field.
Below is a code snippet capturing this entire process (after the snippet I further explain what is happening in the snippet):
String school = schoolEditText.getText().toString().trim();
String password = passwordEditText.getText().toString().trim();
final ParseUser currentUser = ParseUser.getCurrentUser();
currentUser.setPassword(password);
// Query schools and search for name == school, create pointer for that one and put it for user "school"
ParseQuery<ParseObject> query = ParseQuery.getQuery("School");
query.whereEqualTo("name", school);
query.getFirstInBackground(new GetCallback<ParseObject>() {
public void done(ParseObject school_found, ParseException e) {
if (school_found != null) {
Log.d("School", "Retrieved " + school_found.getString("name"));
ParseObject myschoolptr = ParseObject.createWithoutData("School", school_found.getObjectId());
currentUser.put("school", myschoolptr);
} else {
Log.d("School", "Error: School name not found in Database. " + e.getMessage());
}
}
});
currentUser.saveInBackground();
showMainActivity();
In my Parse class School, I have a column labeled name.
I have the user input their school, for example "MIT".
I then query the schools class on parse for an equivalent name.
So that gives me the corresponding ParseObject of school class.
I want to put that in the ParseUsers school field.
However, the ParseUser field for school is a pointer to the School class.
How can I get a pointer to my given ParseObject to put into the user's school field?
You have to call currentUser.saveInBackground(); inside the GetCallback for it to update correctly:
...
query.getFirstInBackground(new GetCallback<ParseObject>() {
public void done(ParseObject school_found, ParseException e) {
if (school_found != null) {
Log.d("School", "Retrieved " + school_found.getString("name"));
ParseObject myschoolptr = ParseObject.createWithoutData("School", school_found.getObjectId());
currentUser.put("school", myschoolptr);
currentUser.saveInBackground();
showMainActivity();
} else {
Log.d("School", "Error: School name not found in Database. " + e.getMessage());
}
}
});
I have an Android app that stores company names and those associated with the companies, using Parse.
I am able to get a column created called ownedby that stores the userID.
Now, I want to store information in the company column where the userID in ownedby equals the current user. Here is the query I am using:
ParseQuery<ParseObject> query = ParseQuery.getQuery("midwifefirm");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> midwives, ParseException e) {
// TODO Auto-generated method stub
if(e==null) {
for (ParseObject midwifefirm : midwives) {
String midwiferelation;
ParseUser currentUser;
String userID;
midwiferelation = midwifefirm.getString("ownedby");
currentUser = ParseUser.getCurrentUser();
userID = currentUser.getObjectId();
if (midwiferelation.equals(userID)) {
midwifefirm.put("yearsinpractice", yearsexperience);
midwifefirm.put("practicename", midwifefirmname);
midwifefirm.put("education", education);
}
}
}
else{
Log.d("notretreive", "Error: " + e.getMessage());
}
}
});
This would seem to work; but in the backend, no data is stored, so I guess my "if statement" never works.
Is there anything obvious I am doing wrong? This is for a thesis project, so I can attempt to fake things a bit for the demo, but would like to learn how to do it right.
Thanks so much
Michael
Not sure I got the code below completely right. But the issue you have lies in the fact that ownedBy is a (as I understand) pointer to a User.
When you then try do midwifefirm.getString("ownedby"), you are not getting the objectId as you expect, instead you get something like {'type':'__pointer', 'class' : '_User', 'objectId' : 'xxx'} (I do not remember the notation but hope you get the idea; the literal pointer string value).
Knowing this it is not odd that an objectId xxx String never can equal midwifefirm.getString("ownedby").
Instead of getString, you can call getParseUser, which will return an empty ParseUser with the correct objectId, recall that the pointer only has the minimal information needed to retrieve the object it points to.
You should now be able to make a direct comparison between your current ParseUser and the pointer ParserUser. The fact that the latter is empty should not matter as it only needs the objectId to perform the comparison.
Try this:
ParseQuery<ParseObject> query = ParseQuery.getQuery("midwifefirm");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> midwives, ParseException e) {
// TODO Auto-generated method stub
if(e==null) {
for (ParseObject midwifefirm : midwives) {
ParseUser midwiferelation;
ParseUser currentUser;
midwiferelation = midwifefirm.getParseUser("ownedby");
currentUser = ParseUser.getCurrentUser();
if (midwiferelation.equals(currentUser)) {
midwifefirm.put("yearsinpractice", yearsexperience);
midwifefirm.put("practicename", midwifefirmname);
midwifefirm.put("education", education);
}
}
}
else{
Log.d("notretreive", "Error: " + e.getMessage());
}
}
});
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'm trying to modify a field for the the currentUser in Parse. I run the following code and my log keeps returning "no results found". I've logged the ObjectId for reference and verified that it's correct in my database.
ParseQuery<ParseUser> query = ParseQuery.getQuery("User");
query.getInBackground(ParseUser.getCurrentUser().getObjectId(), new GetCallback<ParseUser>() {
public void done(ParseUser object, ParseException e) {
if (e == null) {
Log.i("objectId", userObjectId);
object.put("instructorId", instructorId.getText().toString());
object.saveEventually();
} else {
Log.e("objectId", "Error: " + e.getMessage());
Log.i("objectId", userObjectId);
}
}
});
}
});
Your assumption that the User class has the classname User is probably the issue. Try _User.
BUT, you should really be creating your query as
ParseQuery<ParseUser> query = ParseUser.getQuery();
That way you don't even need to know the classname for the user object.