Parse-SDK-Android
Parse-SDK-Android copied to clipboard
ParseUser user.saveEventually() always create new user in database
ParseUser was newly created every time I use user.saveEventually(). I checked in the ParseDashboard, the Installation object for my device is unique but the "user" field in Installation table always different every time I completely close the app (back pressed, wipe out recently apps) and reopen it. The User table has new row too.
My code:
ParseUser.enableAutomaticUser();
ParseUser user = ParseUser.getCurrentUser();
if (user != null) {
ParseACL.setDefaultACL(new ParseACL(ParseUser.getCurrentUser()), true);
if (user.get("appLaunch") == null) {
user.put("appLaunch", 0);
user.put("notifyAll", true);
}
user.saveEventually(); // <-- this line will create new user everytime it run
}
ParseInstallation installation = ParseInstallation.getCurrentInstallation();
if (installation != null) {
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
if (refreshedToken != null) {
installation.setDeviceToken(refreshedToken);
}
installation.put("user", ParseUser.getCurrentUser());
installation.saveEventually();
}
I use latest ParseServer and: implementation "com.parse:parse-android:1.17.3"
I would remove the ParseUser.enableAutomaticUser();
, as you are essentially doing what it does in the next lines. That might be the issue, but maybe not. Try that out first.
@Jawnnypoo If ParseUser.enableAutomaticUser();
was removed, ParseUser.getCurrentUser();
always returns null
. I need to create anonymous user for use in the app.
Btw, If I use user.saveInBackground();
everything works as expected. There must be a bug with user.saveEventually();
.
Also struggling with this, did you encounter any further issues when creating anonymous users with user.saveInBakcground()
for example if you call that when there's no internet connection?
@AlejandroHCruz yes, I still struggle with this issue, the User collection grows very fast compare to Installation collection. For now I switch to use Installation pointer for "relation" instead.
Gotcha, thanks!
user.cryInBackground()
So, the issue is that the ParseAnonymousUser is actually not getting saved properly, which results in no user being available when the app starts again. So the usual path of creating a new anon user is followed. The solution that worked for me was like below:
In my Application file
@Override
public void onCreate() {
...
// Enable automatic creation of ParseAnonymousUser
ParseUser.enableAutomaticUser();
// Login the anonymous user so as to create an entry in the Parse's User table
loginAnonUserIfNeeded()
}
where loginAnonUserIfNeeded()
is another method, which takes care of logging in the ParseAnonymousUser.
void loginAnonUserIfNeeded() {
// If the current user does not have the object id then it is
// an anon user, then go ahead and login the user into parse
if (ParseUser.getCurrentUser() != null
&& ParseUser.getCurrentUser().getObjectId() == null) {
// call to login only creates the anon user but does not persist it
ParseAnonymousUtils.logIn((user, e) -> {
if (e == null) {
// The user returned here is ParseUser object which is now stored in remote Parse
// server. If the login was not successful this will be null. So we check for the
// user object that si returned is not null and login was successful.
if (user != null) {
// After login, save is required so that it persists across app starts
// ⚠️ WARNING: Do not use saveEventually as it is buggy and creates new anon user
// every time app is opened
user.saveInBackground(e1 -> {
if (e1 == null) {
//User was saved successfully
} else {
// Print stacktrace of the error
e1.printStackTrace();
}
});
}
} else {
// Print stacktrace of the error
e.printStackTrace();
}
});
}
}
How to test this: Setup OkHttpInterceptor for logging outgoing calls to Parse Server and you can validate that the create user call is made only once.
I hope this helps others who bump into this problem in the future 😄
Great solution! Please take into account that ParseAnonymousUtils.logIn((user, e) ->
will return a null ParseUser object if there's no internect connection.