1

I've attempted to create a custom self registration page using the Communities Self registration, along with the Site.login and process builder (flows).

Essentially using various steps, when a user's email is verified on a CTA I attempted to activate a user a record and assign permission sets in the same transaction. But due to Salesforce limitation of Mixed DML operation of Non-setup and setup object in the same transaction this process does not seem to work. I wanted this two transactions to happen right away so that when the user was logged in they would be able to properly access all functionality.

Are there any ideas as to how I can attempt my scenario or process?

Currently I came up with the idea of activating the user record right away and having the assign permission sets run as a future or queueable, and when they log in, we first send them to a generic welcome page. Upon clicking on the CTA or button on that page I will look to use Apex Action poller to continuously check if the permissions have been set until we send them to the desired page, but I was wondering or looking to see if there was a better method. Thank you.

1

Here is an approach of separating those actions in two different transactions, otherwise you will face Mixed DML exception.

Visualforce

Use commanButton action for one transaction to create user and then oncomplete event to create permission set in separate transaction.

<apex:pageMessages id="msgId"/>
<script>
        function assignPermissionSetMethod()
        {
            //do other checks if required
            assignPermissionSet();

        }
    </script>

<apex:form id="myForm">
    <apex:actionFunction name="assignPermissionSet" action="{!assignPermissionSet}" reRender="msgId"/>
    <apex:commandButton value="Save" action="{!createUser}"
            oncomplete="return assignPermissionSetMethod();" reRender="msgId"/>
</apex:form>

Controller

public class MyController
{
    public PageReference createUser()
    { 
         //create user record
        return null;
    }

    public PageReference assignPermissionSet()
    {
        //assign permission set of that user

        //here you can return to specific page
        return null;
    }
}

The same principle applies to saving the data and performing callouts in different transactions which I have mentioned in my blog Visualforce webservice callout synchronously & asynchronously

| improve this answer | |
  • Thanks, this seems to be what I wanted. Not sure why I thought of needing to use action poller. Will give this a go, thanks for the documentation. – Hect1c May 11 '18 at 1:48
  • And, also if my answer serves your purpose then you will accept this, so that others may find this useful – Santanu Boral May 11 '18 at 2:00
  • I do have another issue however related to this process which is how can I update the user record with a guest user in order for them to log in? Is the User object accessible by external users? – Hect1c May 11 '18 at 2:31
  • You should use without sharing to run those update in system mode. You can close this question, do your coding on updated approach and post a new question. – Santanu Boral May 11 '18 at 2:33
  • Ok thank you, giving this a go now and will accept this if it all works. – Hect1c May 11 '18 at 2:34
1

You are correct, mixed DML actions are not allowed within the context of a single transaction.

Rather than using an action poller, however, you could simply have the button on your interstitial page trigger the assignment of the permission set and, upon success, return an instance of a Visualforce page that simply redirects to your org's primary domain.

| improve this answer | |
0

This is just an idea, and currently i can't check if it will work for sure, but how about creating update Trigger on User record?

Then check if oldValue for "IsActive" is "false", new is "true" and do that only for users with certain profiles, then assign the permission set using:

PermissionSetAssignment psa = new PermissionSetAssignment(PermissionSetId = myPermissionSetId, AssigneeId = myAssigneeId);
insert psa;
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.