I'm trying to update 1000 items each time with some value in specific column in my DB
ParseQuery<ParseObject> searchQuery = ParseQuery.getQuery("PhoneBook");
searchQuery.whereDoesNotExist("search");
searchQuery.setLimit(1000);
public void done(List<ParseObject> results, ParseException e) {
if (e == null) {
for(ParseObject contact:results){
contact.put("search","someNewValue");
contact.saveInBackground();
}
Toast.makeText(MainActivity.this, "done", Toast.LENGTH_SHORT).show();
} else {
}
}
});
Actually only 200-300 updated even i run on 1000 items.
is there any limit of fast saveInBackground()?
should i use saveEvantually()?
You should store all object in a List and then call saveAllInBackground. Try like this :
searchQuery.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> results, ParseException e) {
if (e == null) {
ArrayList<ParseObject> phoneObjectList=new ArrayList<ParseObject>();
for(ParseObject contact:results){
contact.put("search","someNewValue");
phoneObjectList.add(contact);
}
ParseObject.saveAllInBackground(phoneObjectList, new SaveCallback() {
#Override
public void done(ParseException e) {
// TODO Auto-generated method stub
if(e==null){
Log.d(TAG, "saved successfully");
Toast.makeText(MainActivity.this, "done", Toast.LENGTH_SHORT).show();
}else{
Log.d(TAG, "Error in saving view count :"+e.getMessage());
}
}
});
} else {
}
}
});
I got an email from parse:
Your app ... recently exceeded 75% of your plan's request
limit of 30 requests/second. Additional requests to Parse exceeding
the rate of 30 requests/second will be dropped, returning an error
with error code 155.
saving data might exceed the exceeded 30 requests/second.
so, saving such of big amount of data should take in consideration...
this is how it looks:
Been there, done that. saveAllInBackground() is crappy. I had to use loop for each object with plain saveInBackground() without callback. And yes - 200,300 save objects from 1000 is normal (for that service). It's not designed to work with batch saves I suppose. And yes - it's easy to exceed limit with saving that much.
Related
I'm using Parse as my backend and I'm trying to "like" a post that another user posted on the app. I'm querying to get the post, then incrementing the number of likes by 1, then adding the current user's object ID to an array that holds all the ID's of users which liked the post.
carLikeQuery.getInBackground(carItem.getObjectId(), new GetCallback<ParseObject>() {
#Override
public void done(ParseObject object, ParseException e) {
object.increment("likes");
object.addUnique("usersWhoLike", ParseUser.getCurrentUser().getObjectId());
object.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if(e==null) {
Log.d("SAVE", "Like saved :)");
} else {
Log.e("SAVE", "Not saved :( :" + e.getLocalizedMessage());
}
}
});
}
});
The error I'm getting:
E/SAVE: Not saved :( :java.lang.IllegalArgumentException: Cannot save a ParseUser that is not authenticated.
I saw the source code for the ParseUser from somewhere:
void validateSave() {
if (getObjectId() == null) {
throw new IllegalArgumentException("Cannot save a ParseUser until it has been signed up. Call signUp first.");
}
if (!isAuthenticated() && isDirty()) {
throw new IllegalArgumentException("Cannot save a ParseUser that is not authenticated.");
}
}
Doing the same kind of checking in my code reveals that the the currentUser is AUTHENTICATED and NOT DIRTY.
What could the issue be? To be honest, I want to say that it was working just fine before today, but obviously I was changing something and made a mistake down the line and I can't find it! Any help would be greatly appreciated.
I resolved the issue by creating an entirely new Parse application with the same data structure/layout. It just plain worked without any code changes.
You can follow the issue on GitHub here
I have a user signup method that looks like this:
user.signUpInBackground(new SignUpCallback() {
public void done(ParseException e) {
if (e == null) {
// Link user to the 'User' role
ParseQuery<ParseRole> roleQuery = ParseRole.getQuery();
roleQuery.whereEqualTo("name", "User");
roleQuery.getFirstInBackground(new GetCallback<ParseRole>() {
#Override
public void done(ParseRole parseRole, ParseException e) {
if (e == null) {
//final ParseRole tempParseRl = parseRole;
ParseRelation<ParseUser> tempRel = parseRole.getUsers();
Log.i("ParseRole: ", parseRole.getName().toString());
parseRole.getUsers().add(user);
//TODO: 4. Delete reg key used for this user
}
// Error on Role ACL
else {
dMenuVerData.dismiss();
Toast.makeText(context, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
});
//1. Hide the progress bar
dataVerPBar.setVisibility(View.GONE);
//2. Show okBtn & successTxt
okBtn.setVisibility(View.VISIBLE);
userSuccessTxt.setVisibility(View.VISIBLE);
dataVerTitle.setText("Congratulations!");
//ParseRelation<ParseUser> tempRel = new ParseRelation<ParseUser>();
//tempParseRl.put("users");
} else {
// Dismiss dialog, show Parse error
dMenuVerData.dismiss();
Toast.makeText(context, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
});
On Parse I have two roles created on the data-browser.
After executing the line:
<role>.getUsers().add(user);
I'm expecting to be able to see the recently signed-up user under the "users , instead this table is empty:
What am I missing? Is the
<role>.getUsers().add(user);
working properly? Thanks.
The solution resides in using <role>.saveInBackground(); method after adding a new user to the ParseRelation, so after the signup succeeded I added:
...
parseRole.getUsers().add(user);
parseRole.saveInBackground();
...
I hope this helps.
you are not saving the role after you changed the users relation
what can i see that you added the user to (the local list you get from parseRole.getUsers() but you didn't saved it (to sync the changes with the remote version)
On every launch my app loads fresh data from parse.com and pins all objects to use app without network requests like this^
public void pinKids() {
ParseQuery<ParseObject> query = ParseQuery.getQuery(ParseConstants.CLASS_KIDS);
query.whereEqualTo(ParseConstants.KEY_PARENT, currentUser);
query.findInBackground(new FindCallback<ParseObject>() {
public void done(final List<ParseObject> kidsList, ParseException e) {
if (e == null) {
ParseObject.unpinAllInBackground(ParseConstants.LABEL_KIDS, new DeleteCallback() {
#Override
public void done(ParseException e) {
ParseObject.pinAllInBackground(ParseConstants.LABEL_KIDS, kidsList, new SaveCallback() {
#Override
public void done(ParseException e) {
Log.d("Hello", "pinKids");
}
});
}
});
}
}
});
}
One of the columns in my class is an array of strings (it stores history messages). I found that my code doesn't refresh this array if that array was updated from the other device (the same user did something on the other device). The rest of the data (other columns) refresh without problems. But the array of strings stays as it was downloaded at first launch.
In parse.com dashboard I see that array is updated. But code doesn't download this array while all the other columns are downloaded correctly.
Let me say that when I update this array on device-1 the new data is stored on device-1 and on "parse.com" too. But it doesn't update on device-2.
Please help!
OK! I've solved it.
This problem is a bug of parse.com.
I've created an issue on parse's github.
So I found that my problem is a part of parse's bug.
So the answer is: replace all calls to getJSONArray(key) with getList(key). You might also need revert()/revert(key)
I am using this code for getting a row from the parse cloud but everytime I am fetching objects it is giving me empty list,Although there is a corresponding row available in the parse which I am trying to find and update.
public void onClick(View v) {
ParseQuery<ParseObject> query = ParseQuery.getQuery("StudentInfo");
query.whereEqualTo("rollnum",rollnum.getText().toString());
query.whereEqualTo("name",name.getText().toString());
query.whereEqualTo("city",city.getText().toString());
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
if(e == null && objects.size() > 0){
obj=objects.get(0);
obj.put("rollnum",rollnum.getText()
.toString());
obj.put("name",name.getText().toString());
obj.put("city", city.getText().toString());
obj.saveInBackground();
}
else if(objects.size()==0){
Toast.makeText(getApplicationContext(), "No relation Found!"+e,Toast.LENGTH_LONG).show();
}
}
}
If the object is there I am updating it with new values with help of put method.But it is always giving me an empty list of Parse Objects.
I think you are trying to update the available objects.You can do it this way.
public void onClick(View v) {
ParseQuery<ParseObject> query = ParseQuery.getQuery("StudentInfo");
query.whereEqualTo("rollnum",rollnum.getText().toString());
query.whereEqualTo("name",name.getText().toString());
query.whereEqualTo("city",city.getText().toString());
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
if(e == null ){
if(object.size()==0){
//here you can put object with help of put method if object is not there and when the object size is greater than 1 you remove the other objects except the objects.get(0).All other objects except one will be removed and only the zeroth object will be updated at the time user updates it
}
else if( objects.size() > 0){
obj=objects.get(0);
obj.put("rollnum",rollnum.getText()
.toString());
obj.put("name",name.getText().toString());
obj.put("city", city.getText().toString());
obj.saveInBackground();
}
}
else{
//exception in getting data
}
}
}
If you are getting a empty list of objects then that means there are no objects stored that match the criteria that you are querying against.
Make sure you understand your query. The way you are setting up your query, there has to be a ParseObject stored where the rollnum, name, and city are equal to those values you are testing against, and they must be exactly equal. If no objects match that criteria, then parse will return an empty list. Use the Logcat and Parse Dashboard to debug and find out what's wrong with your query.
After calling code below for several times(5-10 times), done() method for SaveCallback doesn't fire and whole application seems to stuck. It seems that this request ruins request queue and all further queries doesn't fire their callbacks either. No errors in callbacks and in logs. " BEFORE SAVING" - displayed in logs, while " SAVED" - didn't.
Do I need to change parse pricing contract, or to change my code somehow?
Log.d("MESSAGE OBJECT", " BEFORE SAVING");
messageParseObject.saveInBackground(new SaveCallback() {
#Override
public void done(final ParseException e) {
Log.d("MESSAGE OBJECT", " SAVED");
if (e != null){
completitionCallback.error(e);
return;
}
chatObject.put(ModelConstants.LAST_MESSAGE_KEY, messageParseObject);
chatObject.getRelation(ModelConstants.MESSAGES_KEY).add(messageParseObject);
chatObject.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
Log.d("CHAT OBJECT", " SAVED");
if (e == null)
completitionCallback.success();
else
completitionCallback.error(e);
}
});
}
});
Faced this and really drove me crazy. This is what I found. If the Class is already created in Parse.com, even if there is a small discrepancy saveInBackground and saveEventually fails without any error.
Best way, if this happens is to delete the created class in Parse.com and let the android SDK call it it automatically in the first invocation.
At least that did the trick for me.