The find on the db does not complete, so the FindCallback.done() method is never called, no errors, nothing, just is not called. this is the code
ParseQuery<ParseObject> pq = ParseQuery.getQuery("Category").setLimit(1);
pq.getFirstInBackground(new GetCallback<ParseObject>() {
#Override
public void done(ParseObject object, ParseException e) {
throw new RuntimeException();
}
});
I can see the prints before and after this portion of code, but the exception is never thrown. Please, I do really need help.
Edit: I use the parse-login before this point and it works correctly, even the saveInBackground() works correctly, the only problems I find are about queries, (find, getfirst ecc).
Resolved, I found out that the background features offered by Parse do not work if in your activity there are fragments, so you have to implement them yourself. The only strange fact is that in the beginning some function (such saveInBackground as I mentioned above) worked.
Check the ACL column in the parse object row, maybe you don't have permission to read.Double click on the ACL column and check the "public Read".
Thy this:
ParseQuery<ParseObject> pq = ParseQuery.getQuery("Category").setLimit(1);
pq.findInBackground(new FindCallback< ParseObject >() {
#Override
public void done(List< ParseObject > parseObjects, ParseException e) {
// Success
} else {
e.printStackTrace();
}
The pq.getFirstInBackground(new GetCallback<ParseObject>() is meant to return only one object, so you need to help it zero in on that object, for example a particular name or item.
Try adding pq.whereEqualTo("item", biscuit);.
If you want to return a list of objects you need to use a different callback.
End product should look like this.
ParseQuery<ParseObject> pq = ParseQuery.getQuery("Category").setLimit(1);
pq.whereEqualTo("item_key_here", "item_value_here");
pq.getFirstInBackground(new GetCallback<ParseObject>() {
#Override
public void done(ParseObject object, ParseException e) {
if(object != null){
//do stuff here
}
});
Related
i'm having an issue that soon enough going to blow me.
i have Database table lets call it A. table A has field that determines if this row is processed or no. i update the field myself from within the Parse Browser to either True | False, and trying to call query.findInBackground() to check with the Boolean value however the returned List always returns False if its True and vice versa. enough talking let me show you what i'm doing.
public static void getMyRequests(ParseUser user, final FindCallback<ServicesModel> callback) {
ParseQuery<ServicesModel> query = new ParseQuery<>(ServicesModel.class);
if (!user.getBoolean(ParseHelper.CAN_UPLOAD)) {
query.whereEqualTo("user", user);
}
query.findInBackground(new FindCallback<ServicesModel>() {
#Override public void done(final List<ServicesModel> objects, ParseException e) {
if (e == null) {
if (objects != null && !objects.isEmpty()) {
for (ServicesModel object : objects) {
object.setHandlerUser(object.getParseUser("handlerUser"));
object.setProcessedTime(object.getLong("processedTime"));
object.setCategoryType(object.getString("categoryType"));
object.setUser(object.getParseUser("user"));
object.setUserRequest(object.getString("userRequest"));
object.setImageUrl(object.getString("imageUrl"));
object.setProcessed(object.getBoolean("isProcessed"));
Logger.e(object.getBoolean("isProcessed") + "");
}
callback.done(objects, null);
} else {
callback.done(null, new ParseException(1001, "No Services"));
}
} else {
callback.done(null, e);
}
}
});
}
the code above suppose to refresh my data but however my log always shows that isProcessed is False even tho it's set to True inside the Parse Browser
what i have tried besides this? fetchAllInBackground & fetch() you name it. the object will always return false until i re-run the application from Android Studio what i'm doing here wrong? btw here is how i initialize Parse
Parse.setLogLevel(BuildConfig.DEBUG ? DEBUG_LEVEL : Parse.LOG_LEVEL_NONE);
ParseObject.registerSubclass(ProductsModel.class);
ParseObject.registerSubclass(ProductRentalModel.class);
ParseObject.registerSubclass(ServicesModel.class);
Parse.enableLocalDatastore(context);
Parse.initialize(context, context.getString(R.string.app_id), context.getString(R.string.client_id));
the answer was to remove
Parse.enableLocalDatastore(context);
which is bad anyway, without the datastore enabled the data are refreshed probably, however with enabling the local database, the data will not refresh unless if i killed the app and/or re-install it. that's bad. but did the trick.
i am making an android app in which i am getting the data from the server side by making doinbackground method and assigning these values to the variables which are declared globally. Problem is that i am using that variables in oncreate method where it give me null values because the doinbackground method finishes after the variables are used in oncreate. what could be the solution for this?
public void getProfileInfo() {
String currentUserId = ParseUser.getCurrentUser().getObjectId();
ParseQuery<ParseObject> query = ParseQuery
.getQuery(ParseConstants.KEY_USER_INFO);
query.whereEqualTo(ParseConstants.KEY_USER_ID_INFO, currentUserId);
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> objects, ParseException e) {
if (e == null) {
for (ParseObject thisUser : objects) {
name = thisUser
.getString(ParseConstants.TYPE_INFO_FULLNAME);
email = ParseUser.getCurrentUser().getEmail();
}
} else {
Log.d("Activity", "Error: " + e.getMessage());
}
}
});
}
i am calling this method in oncreate before i use the variables name and email.i checked the value of name and email. it gave me the right values.
It sounds like you have a bit of timing problem.
Just to state the obvious, you can't start an asynchronous task on a background thread, and then blindly use the results without knowing that the task has completed.
The use of the results needs to be triggered by the completion of the task.
So, whatever you're doing to access these 'global variables' that is getting nulls - don't do it at a deterministic time (e.g. in onCreate) - do it when you actually get the results back.
If there's a chance that the results may come back before the point where you're currently trying to access them, check to see if they have come back, and if they have, use them. If they haven't, wait until they do come back.
I'll leave the implementation of this as an "exercise for the reader"
I'm using Parse.com in my Android app. I'm making a collaborative shopping list which allows the user to mark items for deletion (they turn grey), but they only get actually deleted when I press the Sync button (and there's a network available). Currently, the objects are erased from parse database but not from the local datastore. I'm trying this:
ParseQuery<ShoppingItem> queryDeletes = ShoppingItem.getQuery();
queryDeletes.fromPin(MyApplication.ALL_ITEMS);
queryDeletes.whereEqualTo("isDeleted", true);
queryDeletes.findInBackground(new FindCallback<ShoppingItem>() {
#Override
public void done(final List<ShoppingItem> items, ParseException e) {
if (e == null) {
ShoppingItem.deleteAllInBackground(items, new DeleteCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
ShoppingItem.unpinAllInBackground(items, new DeleteCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
if (!isFinishing()) {
shoppingListAdapter.loadObjects(); // update the list view
}
}
}
});
}
}
});
}
}
});
}
Already tried clearing app data and overriding equals() in ShoppingItem with no success. Any ideas?
Thanks!
Ok, so I solved it. From what I understood, what I was trying to do is not possible using the parse library.
First of all, deleteAllInBackground() also unpins objects, so the unpinAllInBackground() is not needed.
The problem is that I was pinning the objects using item.pin(MyApplication.ALL_ITEMS), thus the only way to unpin them is by passing the pin name using item.unpinInBackground(MyApplication.ALL_ITEMS). However, the batch version does not allow to pass as argument both a collection of items AND the pin name. Thus, it isn't possible to batch unpin items with a named pin.
I ended up unpinning the objects individually passing the pin name. The big complain I have is that doing item.unpinInBackground() without the pin name does not throw an exception and thus I was not aware what the problem was.
I have an app in which you can upvote things, similar to Facebook likes or Reddit upvotes. You get the picture.
Well, I figured it would just be simple. I have an array column in Parse. For every message that gets an upvote, the user's name gets added to the array in that specific post's row. Except I need to prevent the user from voting an infinite amount of times. Here is what I tried after reading
final ParseQuery<ParseObject> query3 = ParseQuery.getQuery("Messages");
query3.whereContains("objectId", objectId);
query3.whereContains("PostVoteUsers", mCurrentUser.getUsername());
query3.findInBackground(new FindCallback<ParseObject>() {
List<String> list11 = new ArrayList<String>();
public void done(List<ParseObject> messages, ParseException e) {
if (e == null) {
ParseObject p = messages.get(0);
if(p.getList("PostVoteUsers").contains(mCurrentUser.getUsername())==false)
list11 = p.getList("ParseVoteUsers");
if(list11.contains(mCurrentUser.getUsername()))
uparrow.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ParseQuery<ParseObject> query2 = ParseQuery.getQuery("Messages");
query2.getInBackground(objectId, new GetCallback<ParseObject>() {
public void done(ParseObject messages, ParseException e) {
if (e == null) {
int votes = messages.getInt("PostVotes") + 1;
messages.add("PostVoteUsers", mCurrentUser.getUsername());
messages.put("PostVotes", votes);
postvote.setText("" + votes);
messages.saveInBackground();
}
}
});
}
});
}}});
It doesn't work. Everything I try gets me with a nullpointer exception. I've tried a few other things too, but I figured I may be looking at the wrong questions.
In the class "Messages," I have an array column called "PostVoteUsers."
Once and for all, how can I find out if the user is in a specific row's array?
http://i.stack.imgur.com/a2AEq.jpg
Write a function that determines whether the user is in your object's array similar to this:
public boolean canBeLiked() {
String ids = getJSONArray("likedBy").toString();
if (ids.contains(ParseUser.getCurrentUser().getObjectId())) {
return true;
}
return false;
}
But change that to work for you. It works for me. Get the JSONArray of your ParseObject, make it a string, and then call contains(ParseUser.getCurrent().getObjectId()) on that string.
I was making two Parse.com queries ..
ABC.findInBackground(new FindCallback<ParseObject>()
{
...
}
DEF.findInBackground(new FindCallback<ParseObject>()
{
...
}
and I essentially tried doing this,
CountDownLatch waitForBoth = new CountDownLatch(2);
ABC.findInBackground(new FindCallback<ParseObject>()
{
...
waitForBoth.countDown();
}
DEF.findInBackground(new FindCallback<ParseObject>()
{
...
waitForBoth.countDown();
}
// (error handling (just a flag) not shown)
waitForBoth.await();
Log("both are finished yay!");
of course, I just get the sundry errors IllegalMonitorStateException: object not locked by thread before wait() etc etc etc.
Part of the problem other than me being dense is, those calls to Parse's findInBackground in fact, take you off on a new thread anyway, right?
For the record, one of those Parse calls looks like this,
ParseQuery<ParseObject>PQ = ParseQuery.getQuery("SomeTable");
PQ.whereEqualTo("SomeColumn", ParseUser.getCurrentUser());
PQ.include("SomeOtherColumn");
PQ.findInBackground(new FindCallback<ParseObject>()
{
#Override
public void done(List<ParseObject> res, ParseException e)
{
if (e == null)
{
// res is the List of ParseObject results from the cloud
// here, you'd basically...
waitForBoth.countDown();
}
else
{
int errCodeSimple = e.getCode();
exampleWoeFlag = false;
waitForBoth.countDown();
}
}
});
}
and the doco on that ...
http://parse.com/docs/android/api/com/parse/ParseQuery.html#findInBackground(com.parse.FindCallback)
The Parse SDK does create a new Thread, but the "done" method is running on the UI Thread. This means you are calling "countDown" on the UI Thread, but you will never reach there, because you have called "await" on it.
You could solve it by creating your own Threads and passing the CountDownLatch in it. And then use Parse's synchronous methods
does that make sense ? Someone correct me if Im wrong
By the way, there is an excellent (free) course running on coursera at the moment (https://www.coursera.org/course/posa) that discusses the CountDownLatch in Android.
kind regards
Anton