We've build a Salesforce Community and would like to enable Self-Registration. We want to customize this experience so that the user is associated with a Contact and Account that already exists in Salesforce.
Following the help documents on Salesforce, I enabled Self-Registration. We followed this link to the "self-registration Apex controller" and modified the code to locate a matching Contact and Account.
However, we constantly get portal account must have a role error when running the code in the Community (tests all pass without error):
There was an error in registering a user in site My_Community. The error message is: portal account owner must have a role
The default account I setup on in Community Registration setting as an owner with a Role, and the user I'm trying to register has a matching contact whose account has an owner with an assigned Role.
I've found this Stack Exchange question with the same error message, but the user references something called LightningSelfRegisterController
, which I cannot find in my org.
The link "self-registration Apex controller" on the Community Admin page takes you to the CommunitiesSelfRegController
class. I assume that the out-of-the-box Register
page calls that controller, but I'm certain this controller is ever being called. I modified the registerUser()
method like so:
public PageReference registerUser() {
// it's okay if password is null - we'll send the user a random password in that case
if (!isValidPassword()) {
ApexPages.Message msg = new ApexPages.Message(ApexPages.Severity.ERROR, Label.site.passwords_dont_match);
ApexPages.addMessage(msg);
return null;
}
// lookup contact based on email address
// if there's more than one, get the oldest record
Contact cnt = [select Id, AccountId from Contact where AccountId <> null and Email = :email order by CreatedDate limit 1];
// if contact not found, show error and return null
if(cnt == null) {
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, CONTACT_NOT_FOUND));
return null;
}
String profileId = [select Id from Profile where Name = :COMMUNITY_PROFILE_NAME].Id;
// never used
// String roleEnum = null;
String accountId = cnt.AccountId;
String userName = email;
User u = new User();
u.Username = userName;
u.Email = email;
u.FirstName = firstName;
u.LastName = lastName;
u.CommunityNickname = communityNickname;
u.ProfileId = profileId;
u.ContactId = cnt.Id;
String userId;
try {
userId = Site.createExternalUser(u, accountId, password);
} catch(Site.ExternalUserCreateException ex) {
List<String> errors = ex.getDisplayMessages();
for (String error : errors) {
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, error));
}
// This message is used for debugging. Do not display this in the UI to the end user.
// It has the information around why the user creation failed.
System.debug(ex.getMessage());
}
if (userId != null) {
if (password != null && password.length() > 1) {
return Site.login(userName, password, ApexPages.currentPage().getParameters().get('startURL'));
}
else {
PageReference page = System.Page.CommunitiesSelfRegConfirm;
page.setRedirect(true);
return page;
}
}
return null;
}
My questions are:
- Am I on the right path here to enable self-registration with custom contact and account setup?
- Do you see any problems with my code or settings?
- Any idea why I would the
portal account owner must have a role
error when running this in the Community (all my tests pass)?
Appreciate your help.
Best Answer
I answered that question to which you refer. Here's my answer from other there..
The Guest user assigned to new accounts created by community self-registration has no role. I solved this problem by adding logic to the
Insert Before
trigger on theAccount
object that reassigns accounts owned by this user to a "real" user. You may want to come up with a more elegant method that doesn't embed record Id's, but this should work.I believe the real answer to your quest is to create a multi-step VisualForce wizard that creates the account/contact records in one method, and then creates the user you're looking for in the next step. When you get the second step, you should be able to add that contact to a community because you've set
Account.OwnerId
to an owner with a role in theAccount
Trigger.