Monday, June 25, 2018

Sitecore User profile values lost

Hi, 

We are not able to store data in user profile for a virtual user we are creating on login. 

The custom properties do not persist on the next requests. This is very intermittent and works 1 out of 10 times. The same piece of code works in sitecore v8.2 

In subsequent requests after login, we get empty values on the custom properties. The email and names are retrievable. Only the custom properties are lost.

public virtual User LoginWithUserDetailsFromToken(GetUserDetailsResponseModel user)
        {
            // Todo: Revisit this code when we integrate commerce. Need to set just Logged in and commerce customer if commerce enabled.

            var identifiedUser = CreateVirtualUser(user);
            AuthenticationManager.LoginVirtualUser(identifiedUser);
            ContactManager contactManager = new ContactManager();
            contactManager.CreateOrUpdateContact(user.UserName, user.Email);
            Tracker.Current.CheckForNull().Session.IdentifyAs(IdentityConstants.XConnectConstants.ContactIdentifier, user.Email);
            return identifiedUser;
        }

        

        #region private methods

        private User CreateVirtualUser(GetUserDetailsResponseModel user)
        {
            User virtualUser = AuthenticationManager.BuildVirtualUser($"{IdentityConstants.CommerceUserDomain}\\{user.UserName}", true);
            UpdateVirtualUserProfile(virtualUser.Profile, user);
            return virtualUser;
        }

        private void UpdateVirtualUserProfile(UserProfile virtualUserProfile, GetUserDetailsResponseModel user)
        {
            virtualUserProfile.Email = user.Email;
            virtualUserProfile.Name = user.First_Name;
            virtualUserProfile.FullName = $"{user.First_Name} {user.Last_Name}";
            virtualUserProfile.SetCustomProperty(IdentityConstants.ProfileConstants.IsacaIdKey, user.ID);
            virtualUserProfile.Save();
            //virtualUserProfile.Reload();
        }

 
Edited by KAUTILYA PRASAD on Tuesday, June 12, 2018 at 9:07 PM (UTC)

Package name on file server: scsupport_id509887_local.isaca.org_20180612210429.zip  

In the code example above, we are not able to retrieve the custom property  IdentityConstants.ProfileConstants.IsacaIdKey  from the user profile. 1 out 10 times it is saved..

Edited by Nikita Melnichenko on Wednesday, June 13, 2018 at 7:16 PM (UTC)
Hello KAUTILYA,

Please give us some time to check this issue. We will let you know when we have any news. 
Based on the information provided in the ticket and our support priority definitions, the priority of the ticket has been set to Medium.
Please let us know if you have any objections regarding the chosen priority.
Best Regards, Nikita

Edited by Andrey Krupskiy on Wednesday, June 20, 2018 at 12:18 PM (UTC)
Hello,

Sorry for the delay.

Unfortunately I cannot reproduce the issue locally, the custom values are saved between requests in my local instance.
I've spent some time investigating this issue, and here are my findings:

Virtual Users are temporary, so Sitecore doesn't use persistant storage for them. This means that these users are stored in memory, and synchronized between servers using ClientDataStore (which is basically a table in Core database).
It's possible that the data is not synchronized properly, or a cache is not cleared for instance.

In order to check these possible causes, please perform the diagnostic tests below:
  1. If you have loadbalanced environment, please temporarily configure it to sticky session mode - so during a session only one server will be used;
  2. Try calling the code below before accessing custom values:
    if (virtualUser.RuntimeSettings.IsVirtual)
    {
    virtualUser.Profile.Reload();
    }
  3. If the tests above don't have any effect on the issue, please export all the data from ClientData table of Core database and attach it to the ticket for review.
Best regards,
Andrey

 
Edited by KAUTILYA PRASAD on Wednesday, June 20, 2018 at 5:41 PM (UTC)

Thanks Andrew,

The ClientData table is empty. I confirmed that nothing is being saved in that table while debugging as well.

After login, virtualUser.RuntimeSettings.IsVirtual is returning false in the subsequent requests. While immediately after login, in the immediate window, the  virtualUser.RuntimeSettings.IsVirtual is true.

While debugging, during the login process, after I add the custom properties to user profile and login the user using "AuthenticationManager.LoginVirtualUser(identifiedUser);", I don't see the custom properties in the immediate window. So, it is not getting persisted to db.

This is happening on all local developer's machine.


Again for your reference - 
 
public virtual User LoginWithUserDetailsFromToken(GetUserDetailsResponseModel user)
        {
            var identifiedUser = CreateVirtualUser(user);
            AuthenticationManager.LoginVirtualUser(identifiedUser);
                        return identifiedUser;
        }
       
        #region private methods
        private User CreateVirtualUser(GetUserDetailsResponseModel user)
        {
            User virtualUser = AuthenticationManager.BuildVirtualUser($"{IdentityConstants.CommerceUserDomain}\\{user.UserName}", true);
            UpdateVirtualUserProfile(virtualUser.Profile, user);
            return virtualUser;
        }
        private void UpdateVirtualUserProfile(UserProfile virtualUserProfile, GetUserDetailsResponseModel user)
        {
            virtualUserProfile.Email = user.Email;
            virtualUserProfile.Name = user.First_Name;
            virtualUserProfile.FullName = $"{user.First_Name} {user.Last_Name}";
            virtualUserProfile.SetCustomProperty(IdentityConstants.ProfileConstants.IsacaIdKey, user.ID);           
            if (!string.IsNullOrEmpty(user.ChapterNum))
            {
                virtualUserProfile.SetCustomProperty(IdentityConstants.ProfileConstants.IsacaChapterId, user.ChapterNum);
            }
            if (!string.IsNullOrEmpty(user.Chapterrole))
            {
                virtualUserProfile.SetCustomProperty(IdentityConstants.ProfileConstants.IsacaChapterId, user.Chapterrole);
            }
            if (!string.IsNullOrEmpty(user.MemberStatus))
            {
                virtualUserProfile.SetCustomProperty(IdentityConstants.ProfileConstants.IsacaChapterId, user.MemberStatus);
            }
            virtualUserProfile.Save();
            virtualUserProfile.Reload();           
        }


Thanks
Kautilya

 

Edited by KAUTILYA PRASAD on Wednesday, June 20, 2018 at 8:26 PM (UTC)

Some more info, I created a controller, added the following code and added the controller rendering on the page. The user gets logged in and I get the date of birth in the same request. On subsequent requests, dob is empty. Sitecore.Context.User.RuntimeSettings.IsVirtual is false
 
if (!Sitecore.Context.User.IsAuthenticated)
            {
                User virtualUser = Sitecore.Security.Authentication.AuthenticationManager.BuildVirtualUser("extranet\\bertie@bassett.co.uk", true);               
                virtualUser.Roles.Add(Sitecore.Security.Accounts.Role.FromName("extranet\\CustomRole"));               
                virtualUser.Profile.FullName = "Bertie Bassett";
                virtualUser.Profile.Email = "bertie@bassett.co.uk";
                virtualUser.Profile.SetCustomProperty("DateOfBirth", "1980-01-01");
                // Login the virtual user
                Sitecore.Security.Authentication.AuthenticationManager.LoginVirtualUser(virtualUser);
            }
            var dob = Sitecore.Context.User.Profile.GetCustomProperty("DateOfBirth");
 

Edited by KAUTILYA PRASAD on Wednesday, June 20, 2018 at 9:02 PM (UTC)

There is a sitesetting that we added in the config,
disableClientData="false"
It works after that.

Thanks
Kautilya 

Edited by Andrey Krupskiy on Thursday, June 21, 2018 at 7:38 AM (UTC)
Hi Kautilya,

That site setting does indeed affect the ClientDataStore used for custom properties - glad to hear that you found the setting and configured it properly.

Since you have confirmed that custom properties work now, I am setting the 'Request Action' field of the ticket to 'Close this ticket', so the ticket wil be closed automatically in a day.
If you have any further questions on the issue or setting, please feel free to revert that change and post them here.

Best regards,
Andrey 

No comments:

Post a Comment