function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Josh Packer 10Josh Packer 10 

community registration handler

I have nearly completed a registration handler for our community that uses person accounts, but need a little help finishing up.  Below you can see my registration handler class, along with the corresponding test.  
  • Since this is for a community, do I have to specify the Salesforce License type of Customer Community Login user when creating the user?
  • I tried to create a person account, then capture the ContactId to use when creating the user, does that look complete?
Also, both the class and test save, and when the test runs, it says that it covers 100% of the class code, but it fails.  I get the following error:

System.DmlException: Update failed. First exception on row 0 with id 0054C000000M2VbQAK; first error: MIXED_DML_OPERATION, DML operation on setup object is not permitted after you have updated a non-setup object (or vice versa): User, original object: Account: []
Class.FamilySearchRegHandler.updateUser: line 52, column 1
Class.FamilySearchRegHandler_Test.testCreateAndUpdateUser: line 20, column 1

I found this suggestion, but I am not quite sure how to implement it.

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dml_non_mix_sobjects_test_methods.htm

Any suggestions?
 
global class FamilySearchRegHandler implements Auth.RegistrationHandler{

global User createUser(Id portalId, Auth.UserData data){

    RecordType personAccountRecordType =  [SELECT Id FROM RecordType WHERE Name = 'Person Account' and SObjectType = 'Account'];
    Account newPersonAccount = new Account();
        // for person accounts we can not update the Name field instead we have to update the FirstName and LastName individually
        newPersonAccount.FirstName = data.firstName;
        newPersonAccount.LastName =  data.lastName;
        newPersonAccount.RecordType = personAccountRecordType;
        insert newPersonAccount;
    	
    	Contact c = [SELECT AccountId,Id FROM Contact WHERE AccountId = :newPersonAccount.Id];   
    
        //TODO: Customize the username and profile. Also check that the username doesn't already exist and
        //possibly ensure there are enough org licenses to create a user. Must be 80 characters or less.
        User u = new User();
        Profile p = [SELECT Id FROM profile WHERE name='Community - FS - Public'];
        u.username = data.username + '.fscommunity';
        u.email = data.email;
        u.lastName = data.lastName;
        u.firstName = data.firstName;
        String alias = data.username;
        //Alias must be 8 characters or less
        if(alias.length() > 8) {
            alias = alias.substring(0, 8);
        }
        u.alias = alias;
        u.languagelocalekey = UserInfo.getLocale();
        u.localesidkey = UserInfo.getLocale();
        u.emailEncodingKey = 'UTF-8';
        u.timeZoneSidKey = 'America/Denver';
        u.profileId = p.Id;
        u.contactId = c.Id;
        return u;
    } 


global void updateUser(Id userId, Id portalId, Auth.UserData data){
    User u = new User(id=userId);
    //TODO: Customize the username. Must be 80 characters or less.
    //u.username = data.username + '.fscommunity';
    u.email = data.email;
    u.lastName = data.lastName;
    u.firstName = data.firstName;
    //String alias = data.username;
    //Alias must be 8 characters or less
    //if(alias.length() > 8) {
        //alias = alias.substring(0, 8);
    //}
    //u.alias = alias;
    update(u);
}
}
 
@isTest
private class FamilySearchRegHandler_Test {
static testMethod void testCreateAndUpdateUser() {
    FamilySearchRegHandler handler = new FamilySearchRegHandler();
    Auth.UserData sampleData = new Auth.UserData('testId', 'testFirst', 'testLast',
        'testFirst testLast', 'testuser@example.org', null, 'testuserlong@fs.org', 'en_US', 'facebook',
        null, new Map<String, String>{'language' => 'en_US'});
    User u = handler.createUser(null, sampleData);
    System.assertEquals('testuserlong@fs.org.fscommunity', u.userName);
    System.assertEquals('testuser@example.org', u.email);
    System.assertEquals('testLast', u.lastName);
    System.assertEquals('testFirst', u.firstName);
    System.assertEquals('testuser', u.alias);
    insert(u);
    String uid = u.id;
    
    sampleData = new Auth.UserData('testNewId', 'testNewFirst', 'testNewLast',
        'testNewFirst testNewLast', 'testnewuser@example.org', null, 'testnewuserlong', 'en_US', 'facebook',
        null, new Map<String, String>{});
    handler.updateUser(uid, null, sampleData);
    
    User updatedUser = [SELECT userName, email, firstName, lastName, alias FROM user WHERE id=:uid];
    System.assertEquals('testnewuserlong@salesforce.com', updatedUser.userName);
    System.assertEquals('testnewuser@example.org', updatedUser.email);
    System.assertEquals('testNewLast', updatedUser.lastName);
    System.assertEquals('testNewFirst', updatedUser.firstName);
    System.assertEquals('testnewu', updatedUser.alias);
}
}

 
Best Answer chosen by Josh Packer 10
SandhyaSandhya (Salesforce Developers) 
Hi Josh Packer,

As seen from below post you can try using System.runAs(insertedUser)
before your 
insert(u);

https://developer.salesforce.com/forums/?id=906F0000000AWbXIAW
 
Hope this helps you!

Please mark it as solved if this helps you so that it will make available for other as a proper solution.

Thanks and Regards
Sandhya

 

All Answers

SandhyaSandhya (Salesforce Developers) 
Hi Josh Packer,

As seen from below post you can try using System.runAs(insertedUser)
before your 
insert(u);

https://developer.salesforce.com/forums/?id=906F0000000AWbXIAW
 
Hope this helps you!

Please mark it as solved if this helps you so that it will make available for other as a proper solution.

Thanks and Regards
Sandhya

 
This was selected as the best answer
Josh Packer 10Josh Packer 10
That worked.  It passed.  Thanks for the tip.
Lynn ShawLynn Shaw
Josh Packer, trouble maker!  ;)  Josh, a really neat guy, but sadly, no longer a fellow employee.  Wish you were still here!

I am trying to expand on the registration handler Josh wrote to handle different experience identifiers but so far I can't find any examples of anyone that has implemented them.  
Haritha NayaniHaritha Nayani
Hi Josh ,
We are setting up Socila sign on with google on our community pages .We  are  also using person accounts .
We used same code as you provided .We see  below error 
AuthorizationError?ErrorCode=REGISTRATION_HANDLER_ERROR&ErrorDescription=Attempt+to+de-reference+a+null+object&ProviderId=0SO3L0000004CH2&startURL=%2FIdeaTest%2Fs%2F#
Any  suggestions are appreciated.
pandi GSpandi GS
Hi,
in our org, we have one user with salesforce user(Internal) with emailID as test@testcompany.com and another user as community user(External) with same user. In this case when i do singlesign on, i received only internal user in the updateUser method, not the other.. Is anyone know how this selection works?

Thanks
Pandi