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
Related
I have the following code that allows users to update their data:
String username = "Any username that is currently already used by another user";
ParseUser currentUser = ParseUser.getCurrentUser();
if (currentUser != null) {
currentUser.setUsername(username);
currentUser.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
// All good!
} else {
// Error: Account already exists for this username.
Log.e("Error: ", e.getMessage());
}
}
}
});
When the user is trying to update the username with one that is already used by someone else, it throws an error:
Account already exists for this username.
Which is exactly what I'd want it to, but when the user goes back (without making another request to change the username to one that is available) the ParseUser.get("username") returns the value that wasn't saved because it already exists (instead of the real value stored at the moment in the server).
ParseUser currentUser = ParseUser.getCurrentUser();
currentUser.fetchInBackground(new GetCallback<ParseUser>() {
public void done(ParseUser user, ParseException exception) {
if (exception == null) {
// username now returns ("Any username that is currently already used by another user").
String username = user.get("username").toString().trim();
} else {
// Error
}
}
});
The only way I've found so far to fix the issue is by uninstalling/reinstalling the app. What's causing this? And is there any good way to fix this?
You should backup the current username before setUsername(newName).
if exception happened you have two options either :
Re fetch the user object by ParseUser.getCurrentUser().fetch() (to restore the object to his previous state)
Re set the username to the previous value(that you already back up before)
Why this happened ?
because when you called the setUsername() of the user object you changed your local copy of the object (but you didn't sync it yet with the server) and then when you made save() and the save operation failed the local copy still has the latest changes that you made locally
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 not sure if I am missing a step in the process of linking a Facebook account to an existing Parse User.
This is the code I am using, as per Parse.com
if (!ParseFacebookUtils.isLinked(currentUser)) {
ParseFacebookUtils.linkWithReadPermissionsInBackground(currentUser, getActivity(), null, new SaveCallback() {
#Override
public void done(ParseException ex) {
if (ex == null) {
if (ParseFacebookUtils.isLinked(currentUser)) {
Log.d("MyApp", "Woohoo, user logged in with Facebook!");
}
} else {
Log.e(TAG, ex.getMessage());
}
}
});
}
I am not receiving any type of error, and it will successfully open up the Facebook activity to accept/cancel giving access to my application. The issue that I am finding, is that the authData section inside my User record, inside Parse, is never populated.
What am I doing wrong that my Parse User is not receiving any authData?
Do you happen to add the code to fragment?
If you do that, you should consider about onActivityForResult.
As you know, onActivityForResult is not called normally.
I want to update a field from table 'User' of a ParseUser different by the one logged in.
The code below is not working and I was wondering if there is some impediment that does not allow to update other's user info.
ParseQuery<ParseUser> userQuery = ParseUser.getQuery();
userQuery.whereMatches("objectId", "4mdsJKKgDJ");
userQuery.getFirstInBackground(new GetCallback<ParseUser>() {
#Override
public void done(ParseUser parseUser, ParseException e) {
// I retreive the parseUser object correctly here
int score = parseUser.getInt("score"); // I have added this column in User table with a default value of 0
parseUser.put("score", score+1);
parseUser.saveInBackground(); // nothing happens. the value is not updated
}
});
Thanks.
I answer myself to my question: you cannot update another user info, different by the one logged in.
Using:
parseUser.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
System.out.println("ParseException: "+ e);
}
});
revealed the problem:
com.parse.ParseException: java.lang.IllegalArgumentException: Cannot save a ParseUser that is not authenticated.
So I will need to use another table to keep this info.
Hi I read the tutorials on basic parse features, etc. and I am using the ParseUser feature. From the tutorial this is shown :
ParseUser.logInInBackground("Jerry", "showmethemoney", new LogInCallback() {
public void done(ParseUser user, ParseException e) {
if (user != null) {
// Hooray! The user is logged in.
} else {
// Signup failed. Look at the ParseException to see what happened.
}
}
});
I was wondering how I could look at the ParseException to see what happened. For example, I want to inform the user that a bad username was entered, or a bad password.
Thank you
a Pretty easy way to resolve this is to use
e.getMessage();
// this probably shows you appropriate message
// or you can use
e.getCode();
// and match code with the integers given in Parse Doucmentation
// for example.
// e.EMAIL_NOT_FOUND is code for when email is not found in registered users class
if you need see the exception, can try show in the log or where you decide, in your code for te show in the log where Log.d(nameofalert,mensaje), only need see the logcat for the identify your exception
ParseUser.logInInBackground("Jerry", "showmethemoney", new LogInCallback() {
public void done(ParseUser user, ParseException e) {
if (user != null) {
Log.d("user not null",e.toString());
} else {
Log.d("error",e.toString());
// Signup failed. Look at the ParseException to see what happened.
}
}
});
Place your code in between try catch and in the catch block try to handle stuff that will go when user enter bad username or password
try{
}
catch(ParseException e)
{
// do stuff here
}
how about just doing e.printStackTrace(), that will print all the information that you need pertaining to the exception