I am trying to logout from the current user. Login as another user, delete that user. Come back to the original user. This is what I have so far... It works fine, except it does not log back in the original user... It says Invalid Session Token. But this session token was retrieved using currentUser.getSessionToken() How could it be invalid??
PS: I have enabled the session on parse dashboard and in the app:
ParseUser.enableRevocableSessionInBackground();
Code:
ParseUser currentUser = ParseUser.getCurrentUser();
final String sessionToken = currentUser.getSessionToken();
Log.d(TAG, currentUser.getObjectId() + " sessionToken: " + sessionToken);
ParseUser.logOut();
ParseUser.logInInBackground(userTest, passTest, new LogInCallback() {
#Override
public void done(final ParseUser onlineUser, ParseException e) {
if ((e == null) && (onlineUser != null)) {
Log.d(TAG, "onlineUser.deleteInBackground...");
onlineUser.deleteInBackground(new DeleteCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.d(TAG, "onlineUser.deleted!");
ParseUser.logOut();
ParseUser.becomeInBackground(sessionToken, new LogInCallback() {#Override
public void done(ParseUser user, ParseException e) {
if ((e == null) && (user !=null)){
Log.d(TAG, "user retrieved...");
} else {
Log.d(TAG, "user failed to be retrieved...");
if (e != null) Log.d(TAG, "ParseUser.becomeInBackground ERROR: " + e.toString());
}
});
}
}
});
}
}
});
Related
i'm tryng to integrate facebook login in my android application. For now i get a new row in Parse Backend about the logged user which contains his real name, some weird value(ex:SnvvKEsIv6tX7...) in his userName, and an authData which is Json and contains the following values:
access_token, expiration date, id.
After debugging i got the url of the json response, it only contains two values, the name and the id, however i declared the list like this:
List permissions = Arrays.asList("public_profile", "email");
So for now the graph is only returnin two values, i thought it was due to the permissions but as i sayed i did declared. Here is my code:
public class LoginActivity extends Activity {
private Dialog progressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FacebookSdk.sdkInitialize(getApplicationContext());
ParseFacebookUtils.initialize(this);
// Check if there is a currently logged in user
// and it's linked to a Facebook account.
ParseUser currentUser = ParseUser.getCurrentUser();
if ((currentUser != null) && ParseFacebookUtils.isLinked(currentUser)) {
// Go to the user info activity
showUserDetailsActivity();
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
ParseFacebookUtils.onActivityResult(requestCode, resultCode, data);
}
public void onLoginClick(View v) {
progressDialog = ProgressDialog.show(LoginActivity.this, "", "Logging in...", true);
List<String> permissions = Arrays.asList("public_profile", "email");
// NOTE: for extended permissions, like "user_about_me", your app must be reviewed by the Facebook team
// (https://developers.facebook.com/docs/facebook-login/permissions/)
ParseFacebookUtils.logInWithReadPermissionsInBackground(this, permissions, new LogInCallback() {
#Override
public void done(ParseUser user, ParseException err) {
progressDialog.dismiss();
if (user == null) {
Log.d("TAG", "Uh oh. The user cancelled the Facebook login.");
} else if (user.isNew()) {
GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject fbUser,
GraphResponse response) {
/*
* If we were able to successfully retrieve the
* Facebook user's name, let's set it on the
* fullName field.
*/
Log.e("facebook User", fbUser.toString());
final ParseUser parseUser = ParseUser
.getCurrentUser();
if (fbUser != null
&& parseUser != null
&& fbUser.optString("name").length() > 0) {
parseUser.put("name",
fbUser.optString("name"));
parseUser.put("email",
fbUser.optString("email"));
Log.v("isnew, values: ","values : "+fbUser.optString("name")+","+fbUser.optString("email")+","+fbUser.optString("age_range")+","+fbUser.optString("locale"));
parseUser
.saveInBackground(new SaveCallback() {
#Override
public void done(
ParseException e) {
if (e != null) {
Log.v("", (getString(R.string.com_parse_ui_login_warning_facebook_login_user_update_failed)
+ e.toString()));
}
ParseInstallation installation = ParseInstallation
.getCurrentInstallation();
installation
.put(ParseConstants.KEY_USER_ID,
parseUser
.getUsername());
installation
.saveInBackground();
showUserDetailsActivity();
}
});
}
}
}).executeAsync();
} else {
Log.d("TAG", "User not new logged in through Facebook!");
showUserDetailsActivity();
}
}
});
}
private void showUserDetailsActivity() {
Intent intent = new Intent(this, UserDetailsActivity.class);
startActivity(intent);
}
}
public class UserDetailsActivity extends Activity {
private ProfilePictureView userProfilePictureView;
private TextView userNameView;
private TextView userGenderView;
private TextView userEmailView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.userdetails);
userProfilePictureView = (ProfilePictureView) findViewById(R.id.userProfilePicture);
userNameView = (TextView) findViewById(R.id.userName);
userGenderView = (TextView) findViewById(R.id.userGender);
userEmailView = (TextView) findViewById(R.id.userEmail);
//Fetch Facebook user info if it is logged
ParseUser currentUser = ParseUser.getCurrentUser();
if ((currentUser != null) && currentUser.isAuthenticated()) {
makeMeRequest();
}
}
#Override
public void onResume() {
super.onResume();
ParseUser currentUser = ParseUser.getCurrentUser();
if (currentUser != null) {
// Check if the user is currently logged
// and show any cached content
updateViewsWithProfileInfo();
} else {
// If the user is not logged in, go to the
// activity showing the login view.
startLoginActivity();
}
}
private void makeMeRequest() {
GraphRequest request = GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject jsonObject, GraphResponse graphResponse) {
if (jsonObject != null) {
JSONObject userProfile = new JSONObject();
try {
userProfile.put("facebookId", jsonObject.getLong("id"));
userProfile.put("name", jsonObject.getString("name"));
if (jsonObject.getString("gender") != null)
userProfile.put("gender", jsonObject.getString("gender"));
if (jsonObject.getString("email") != null)
userProfile.put("email", jsonObject.getString("email"));
// Save the user profile info in a user property
ParseUser currentUser = ParseUser.getCurrentUser();
currentUser.put("profile", userProfile);
currentUser.saveInBackground();
// Show the user info
updateViewsWithProfileInfo();
} catch (JSONException e) {
Log.d("TAG",
"Error parsing returned user data. " + e);
}
} else if (graphResponse.getError() != null) {
switch (graphResponse.getError().getCategory()) {
case LOGIN_RECOVERABLE:
Log.d("TAG",
"Authentication error: " + graphResponse.getError());
break;
case TRANSIENT:
Log.d("TAG",
"Transient error. Try again. " + graphResponse.getError());
break;
case OTHER:
Log.d("TAG",
"Some other error: " + graphResponse.getError());
break;
}
}
}
});
request.executeAsync();
}
private void updateViewsWithProfileInfo() {
ParseUser currentUser = ParseUser.getCurrentUser();
if (currentUser.has("profile")) {
JSONObject userProfile = currentUser.getJSONObject("profile");
try {
if (userProfile.has("facebookId")) {
userProfilePictureView.setProfileId(userProfile.getString("facebookId"));
} else {
// Show the default, blank user profile picture
userProfilePictureView.setProfileId(null);
}
if (userProfile.has("name")) {
userNameView.setText(userProfile.getString("name"));
} else {
userNameView.setText("");
}
if (userProfile.has("gender")) {
userGenderView.setText(userProfile.getString("gender"));
} else {
userGenderView.setText("");
}
if (userProfile.has("email")) {
userEmailView.setText(userProfile.getString("email"));
} else {
userEmailView.setText("");
}
} catch (JSONException e) {
Log.d("TAG", "Error parsing saved user data.");
}
}
}
public void onLogoutClick(View v) {
logout();
}
private void logout() {
// Log the user out
ParseUser.logOut();
// Go to the login view
startLoginActivity();
}
private void startLoginActivity() {
Intent intent = new Intent(this, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
i'm using Parse 1.9.4 and ParseFacebookUtils 1.9.4.
Need to fetch twitter user profile data after successfully logging in using parse. Please refer below code :
ParseTwitterUtils.logIn(SignupActivity.this, new LogInCallback() {
#Override
public void done(ParseUser parseUser, ParseException e) {
if (parseUser == null) {
Log.d("MyApp", "Uh oh. The user cancelled the Twitter login.");
} else if (parseUser.isNew()) {
Log.d("MyApp", "User signed up and logged in through Twitter!");
} else {
Log.d("MyApp", "User logged in through Twitter!");
}
}
});
I tried to get values from Parseuser object returned after login but it is showing null.
Suggest what should I do after logging in.
Thanks
First off: Are you sure that you are logged in? To verify this, make sure that in your console there is the Log "User logged in through Twitter!", if so, you can add:
String twitter = ParseTwitterUtils.getTwitter().getScreenName();
Log.d(MainActivity.class.getSimpleName(), twitter + "");
under your else if and else block, or you can replace your code with this:
ParseTwitterUtils.logIn(SignupActivity.this, new LogInCallback() {
#Override
public void done(ParseUser parseUser, ParseException e) {
if (parseUser == null) {
Log.d("MyApp", "Uh oh. The user cancelled the Twitter login.");
} else if (parseUser.isNew()) {
Log.d("MyApp", "User signed up and logged in through Twitter!");
String twitter = ParseTwitterUtils.getTwitter().getScreenName();
Log.d(MainActivity.class.getSimpleName(), twitter + "");
} else {
Log.d("MyApp", "User logged in through Twitter!");
String twitter = ParseTwitterUtils.getTwitter().getScreenName();
Log.d(MainActivity.class.getSimpleName(), twitter + "");
}
}
});
If your class is not "MainActivity", type it in the Log.d.
If you are having trouble singing in, you can also try this:
user = new ParseUser();
user.setUsername("Username");
user.setPassword("password");
user.setEmail("email#example.com");
user.signUpInBackground(new SignUpCallback() {
public void done(ParseException e) {
if (e == null) {
// Hooray! Let them use the app now.
} else {
// Sign up didn't succeed. Look at the ParseException
// to figure out what went wrong
}
}
});
if (!ParseTwitterUtils.isLinked(user)) {
ParseTwitterUtils.link(user, this, new SaveCallback() {
#Override
public void done(ParseException ex) {
if (ParseTwitterUtils.isLinked(user)) {
Log.d("MyApp", "Woohoo, user logged in with Twitter!");
String twitter = ParseTwitterUtils.getTwitter().getScreenName();
Log.d(MainActivity.class.getSimpleName(), twitter + "");
}
}
});
}
define "ParseUser user;" outside the onCreate method.
I'm trying to make an android app using parse that allows one to login using either their username or email. I have tried querying to get an object with a provided email address, then get that object's username to login with. However, I am getting this error:
'getFirstInBackground(com.parse.GetCallback)' in 'com.parse.ParseQuery' cannot be applied to '(anonymous com.parse.GetCallback "com.parse.ParseObject>)'
I'm new to app dev and parse, so I'm not entirely sure what this means. From what I understand it wont let me use getFirstInBackground because that works with parseUser's and I'm working with ParseObjects, but the code I'm using I pulled from a prior stackoverflow question where this was a working answer: Login username AND email in Parse Android
Here is my code:
// Do this to allow for username or email log in
if (mEmail.indexOf("#") != -1) {
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.whereEqualTo("email", mEmail);
query.getFirstInBackground(new GetCallback<ParseObject>() {
public void done(ParseObject object, ParseException e) {
if (object == null) {
Log.d("score", "The getFirst request failed.");
} else {
String actualUsername = object.getString("username");
ParseUser.logInInBackground(actualUsername, mPassword, new LogInCallback() {
#Override
public void done(ParseUser parseUser, ParseException e) {
if (e != null) {
// TODO: Show error message
Toast.makeText(LoginActivity.this, "Credentials incorrect", Toast.LENGTH_LONG).show();
} else {
// Start Intent for activity
// TODO: Choose activity
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
}
}
});
}
}
});
According to docs, the method's signature is as follows:
class com.parse.ParseQuery<T> {
public void getFirstInBackground(GetCallback<T> callback)
}
That means that the generic type of GetCallback must be the same as in your ParseQuery. So it probably should be
query.getFirstInBackground(new GetCallback<ParseUser>()) { /* ... */ }
You are attempting to query a ParseUser with a GetCallBack of type ParseObject.
Replace all instances of ParseObject with ParseUser in your code.
query.getFirstInBackground(new GetCallback<ParseUser>() {
public void done(ParseUser user, ParseException e) {
if (object == null) {
Log.d("score", "The getFirst request failed.");
} else {
String actualUsername = user.getUsername();
ParseUser.logInInBackground(actualUsername, mPassword, new LogInCallback() {
#Override
public void done(ParseUser parseUser, ParseException e) {
if (e != null) {
// TODO: Show error message
Toast.makeText(LoginActivity.this, "Credentials incorrect", Toast.LENGTH_LONG).show();
} else {
// Start Intent for activity
// TODO: Choose activity
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
}
}
});
}
}
});
Hope this helps
final String userOrEmal = editTextEmailOrUserName.getText().toString().trim();
final String mpassword = editTextPassword.getText().toString().trim();
if (userOrEmal.contains("#")) {
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.whereEqualTo("email", userOrEmal);
query.getFirstInBackground(new GetCallback<ParseUser>() {
#Override
public void done(ParseUser object, ParseException e) {
if (object != null) {
ParseUser.logInInBackground(object.getString("username"), mpassword, new LogInCallback() {
public void done(ParseUser user, ParseException e) {
if (user != null) {
Log.v("login", "secessful");
} else {
Log.v("login", "fail");
}
}
});
} else {
}
}
});
} else {
ParseUser.logInInBackground(userOrEmal,mpassword, new LogInCallback() {
public void done(ParseUser user, ParseException e) {
if (user != null) {
Log.v("login", "secessful");
} else {
Log.v("login", "fail");
}
}
});
}
I am writing a Parse Android application which uses anonymous users by enabling automatic user creation. I can successfully signup this user (to convert the anonymous user into a regular user) and after that, logging in. Both calls return successfully. When I then set data on the user object and trying to save the user, I get a stackoverflow in the ParseObject class.
My code looks like this (simplified example code):
user.setUsername("MyUserName");
final String password = new PasswordGenerator().nextSessionId();
user.setPassword(password);
try {
user.signUp();
ParseUser.logInInBackground(verification.getPhoneNumber(), password, new LogInCallback() {
#Override
public void done(final ParseUser parseUser, final ParseException e) {
if (parseUser == null) {
requestListener.onError(e);
} else {
parseUser.put("phone_no", "123");
parseUser.saveInBackground(new SaveCallback() { // This generates a stackoverflow
#Override
public void done(final ParseException e) {
int i = 0;
System.out.println("i = " + i);
}
});
// requestListener.onSuccess(null);
}
}
});
} catch (ParseException e) {
e.printStackTrace();
}
The stack overflow is generated when calling saveInBackground on the ParseUser. The stackoverflow looks like this:
java.lang.StackOverflowError
at com.parse.ParseObject.isDataAvailable(ParseObject.java:3212)
at com.parse.ParseObject.checkGetAccess(ParseObject.java:3284)
at com.parse.ParseObject.getString(ParseObject.java:2867)
at com.parse.ParseUser.getUsername(ParseUser.java:401)
at com.parse.ParseUser.signUpAsync(ParseUser.java:665)
at com.parse.ParseUser.resolveLazinessAsync(ParseUser.java:1397)
at com.parse.ParseUser.saveAsync(ParseUser.java:502)
at com.parse.ParseUser.signUpAsync(ParseUser.java:681)
at com.parse.ParseUser.resolveLazinessAsync(ParseUser.java:1397)
at com.parse.ParseUser.saveAsync(ParseUser.java:502)
at com.parse.ParseUser.signUpAsync(ParseUser.java:681)
The Parse version I use is 1.8.0.
Any ideas?
I found the solution! Turns out you have to save the anonymous user first before converting the user into a registered one. If you save the user first, convert the user into a registered one and then do a saveInBackground, you won't get a stackoverflow. So the full code to convert an anonymous user is:
final String accountUsername = username.getText().toString();
final String accountPassword = password.getText().toString();
final ParseUser user = ParseUser.getCurrentUser();
user.setUsername(accountUsername);
user.setPassword(accountPassword);
user.signUpInBackground(new SignUpCallback() {
#Override
public void done(final ParseException e) {
if (e != null) {
Toast.makeText(MainActivity.this, "Signup Fail", Toast.LENGTH_SHORT).show();
e.printStackTrace();
} else {
Toast.makeText(MainActivity.this, "Signup success", Toast.LENGTH_SHORT).show();
final ParseUser user = ParseUser.getCurrentUser();
user.put("phone_no", "31743379507");
user.saveInBackground(new SaveCallback() {
#Override
public void done(final ParseException e) {
if (e != null) {
Toast.makeText(MainActivity.this, "Save data Fail", Toast.LENGTH_SHORT).show();
e.printStackTrace();
} else {
Toast.makeText(MainActivity.this, "Save data success", Toast.LENGTH_SHORT).show();
}
}
});
}
}
});
Please note that the saveInBackground in the SignupCallback is optional. You could also set this data on the user before the signUpInBackground is called and save an extra roundtrip. This is pure for demonstration purposes.
Also, it is assumed the following code is placed in the Application class to allow anonymous users:
ParseUser.enableAutomaticUser();
ParseUser.getCurrentUser().saveInBackground();
Here you see the user is saved as soon it is created.
findViewById(R.id.createUser).setOnClickListener(newView.OnClickListener() {
#Override
public void onClick(final View v) {
final String accountUsername = username.getText().toString();
final String accountPassword = password.getText().toString();
final ParseUser user = ParseUser.getCurrentUser();
user.setUsername(accountUsername);
user.setPassword(accountPassword);
user.signUpInBackground(new SignUpCallback() {
#Override
public void done(final ParseException e) {
if (e != null) {
Toast.makeText(MainActivity.this, "Signup Fail",
Toast.LENGTH_SHORT).show();
Log.e(TAG, "Signup fail", e);
} else
{ Toast.makeText(MainActivity.this,"Signupsuccess",Toast.LENGTH_SHORT).show();
final ParseUser user = ParseUser.getCurrentUser();
user.put("phone_no", "31612345678");
user.saveInBackground(new SaveCallback() {
#Override
public void done(final ParseException e) {
if (e != null) {
Toast.makeText(MainActivity.this, "Save data Fail", Toast.LENGTH_SHORT).show();
Log.e(TAG, "Signup fail", e);
} else {
Toast.makeText(MainActivity.this, "Save
data success", Toast.LENGTH_SHORT).show();
}
}
});
}
}
});
}
})
I want a unique user but I don't need it to be a formal thing for my app. So, on launch I inspect shared preferences for a previously stored username. I handle the user creation or login like so:
String parseUsername = _appPrefs.getParseUsername();
_progress.setVisibility(View.VISIBLE);
if (parseUsername == null) {
Log.v(TAG, "Creating a user.");
ParseUser.enableAutomaticUser();
_user = ParseUser.getCurrentUser();
_user.setPassword("abc123");
_user.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.w(TAG, String.format("User '%s' created.", _user.getUsername()));
_progress.setVisibility(View.GONE);
_appPrefs.saveParseUsername(_user.getUsername());
createStory();
return;
}
Log.e(TAG, "Error creating user: ", e);
}
});
} else {
Log.v(TAG, String.format("Logging the user '%s' in with password '%s'.", parseUsername, "abc123"));
ParseUser.logInInBackground(parseUsername, "abc123", new LogInCallback() {
#Override
public void done(ParseUser user, ParseException e) {
Log.v(TAG, "User logged in.");
_progress.setVisibility(View.GONE);
if (e == null) {
createStory();
return;
}
Log.e(TAG, "Error logging in: ", e);
}
});
}
I can see the user being successfully created in the logs. I can kill the app and re-launch but it always fails with "invalid login credentials" response from Parse.
If I manually enter abc123 in the Parse data browser then everything works. Ideas?