I have member and non-member profiles. Based on a field(checkbox) on contact object the profile should change automatically. Currently it is doing the functionality but if multiple users change the field on multiple records, profile change is not happening because it is going to queue. How can i make it work without going to queue and change profiles.


 public void userprofile(){
        if (!System.isBatch() && !System.isFuture())
                  UpdateUserProfileTriggerHandler.updateProfile ();


    public static void updateProfile(){
       System.debug('inside update profile');
        List<id> userids = new list<id>();

        Profile porfileMember = [SELECT Id FROM Profile WHERE Name='Member' limit 1];
        Profile porfileNonMember = [SELECT Id FROM Profile WHERE Name='NonMember' limit 1];
        List<User> Uv = [Select ProfileId,IsActive,contactId from User];
        Map<Id, User> mapusers = new Map<Id, User>();
        for(user u: Uv){
        List<contact> cntList = [select id, Member__c  from contact where id IN:userids];   
         System.debug('before for loop update profile');
        List<User> UpdateList = new List<User>();
        for(contact cnt: cntList){
             System.debug('TestingContact-' + cnt.id);
              if(mapusers.containsKey(cnt.id)) {

                 User usr = mapusers.get(cnt.id);

                if(cnt.Member__c == false){
                    usr.ProfileId =porfileNonMember.Id;
                    usr.IsActive = True;

                    usr.ProfileId  =porfileMember.Id;
                    usr.IsActive = True;


Trigger : trigger UpdateUserProfileTrigger on Contact (before update) {

UpdateUserProfileTriggerHandler handler = new UpdateUserProfileTriggerHandler(); handler.userprofile(); // UpdateUserProfileTriggerHandler.updateProfile(); /* string id = ''; for(Contact c: Trigger.new){ id = c.Id;

     UpdateUserProfileTriggerHandler handler = new UpdateUserProfileTriggerHandler();
  • any reason why your running this in @future context? Seems like you could run this real time within the trigger? Apr 25, 2016 at 14:34
  • Running in future to get rid of "MIXED_DML_OPERATION, DML operation on setup object is not permitted after you have updated a non-setup object" error. @BenjaminPirih
    – user30968
    Apr 25, 2016 at 14:36

1 Answer 1


I think problem is that you are selecting all users, and all contacts. But actually you need to check only one field for particular contract.

  • try after trigger, since you aren't going to modify contacts
  • check particular field for contact and collect its id
  • select correspondent users and then update their profiles

Please try this:

trigger UpdateUserProfileTrigger on Contact (after insert, after update) {
set<id> contactIds = new set<id>();
for (contact con :trigger.new){
    //check that particular field was modified
    if ( trigger.oldMap.get(con.Id).Member__c != con.Member__c )
//select correspondent users
list<user> usersToBeUpdated = new list<user>([select id, contactid from user where contactid in :contactIds ]);
//use one select for profile
map <string, id> profileIdByNameMap = new map <string, id>();
for ( profile pr : [SELECT Id FROM Profile WHERE Name in ('Member', 'NonMember')])
    profileIdByNameMap.put(pr.name, pr.id);
//modify user profile
for (user usr :usersToBeUpdated){
    if (trigger.newMap.get(usr.contactid).Member__c) {//this is already BOOLEAN type,
        usr.ProfileId = profileIdByNameMap.get('Member');
    } else {
        usr.ProfileId = profileIdByNameMap.get('NonMember'); 
if (!usersToBeUpdated.isEmpty())
    update usersToBeUpdated;

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .