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
ankushankush 

"Future method cannot be called from a future" error in trigger

 Getting the error when validating
 Future method cannot be called from a future or batch method: contactactivecheckboxclass1.updatecnt1(Id) Trigger.Checkuseractive: line 15, column 1. Can some please guide

Trigger 
//This is a trigger that is used to check whether the user is active and updates the related Contact
trigger Checkuseractive on User (after insert, after update) {
   
    //Below soql query gets the IsActive and ContactId of the user
 list<user> u=[select id,Isactive,contactid from user where id=:trigger.new];
    for(user usr:u){
    Id cid=usr.ContactId;
    if(usr.IsActive==false)
    {
        contactactivecheckboxclass.Updatecnt(cid);
        
    }
        else if(usr.IsActive==true)
    {
        contactactivecheckboxclass1.Updatecnt1(cid);
        
    }
        }
}

Class

//Future class for updating Contact Active Checkbox field
public class contactactivecheckboxclass1 {
@future
    //Method that takes the contact id as parameter from Trigger and checks if user is active on user Object and updates the related contact accordingly.
     public static void updatecnt1(id x){
         try{
    contact c=[select Is_user_Active__c from Contact where id=:x limit 1];
    c.Is_User_Active__c=true;
    if(!test.isrunningtest()){

        database.update(c);
         }
         }
         catch(exception e){
          
          
      }
   } 
}
Best Answer chosen by ankush
Tejpal KumawatTejpal Kumawat
Please Check these working fine on my org:

public class ProcessorControl {
    public static boolean inFutureContext = false;
    public static boolean inFutureContext2 = false;
}


public class contactactivecheckboxclass {
    @future
    //Method that takes the contact id as parameter from Trigger and checks if user is active on user Object and updates the related contact accordingly.
    public static void updatecnt(set<string> x){
        try{
            list<contact> cntlist= new list<contact>();
            list<contact> c=[select Is_user_Active__c from Contact where id IN : x limit 1];
            for(contact cnt:c){
            cnt.Is_User_Active__c=false;
            if(!test.isrunningtest()){
                cntlist.add(cnt);
            }
            }
            ProcessorControl.inFutureContext = true;
            database.update(cntlist);
        }
        catch(exception e){
        }
    } 
}


public class contactactivecheckboxclass1 {
    @future
    //Method that takes the contact id as parameter from Trigger and checks if user is active on user Object and updates the related contact accordingly.
    public static void updatecnt1(set<string> x){
        try{
            list<contact> cntlist= new list<contact>();
            list<contact> c=[select Is_user_Active__c from Contact where id IN : x limit 1];
            for(contact cnt:c){
            cnt.Is_User_Active__c=true;
            if(!test.isrunningtest()){
                 cntlist.add(cnt);
            }
            }
             ProcessorControl.inFutureContext2 = true;
            database.update(cntlist);
            }
        
        catch(exception e){
        }
    } 
}

trigger Checkuseractive on User (after insert, after update) {
    set<string> set1 = new set<string>();
    set<string> set2 = new set<string>();
    
    //Below soql query gets the IsActive and ContactId of the user
    //list<user> u=[select id,Isactive,contactid from user where id=:trigger.new];
    for(user usr:trigger.new){
        if(usr.IsActive==false)
        {
        set1.add(usr.ContactId);
        }
        else if(usr.IsActive==true)
        {
        set2.add(usr.ContactId);
        }
    }
    if (!ProcessorControl.inFutureContext) 
        contactactivecheckboxclass.Updatecnt(set1);
    if (!ProcessorControl.inFutureContext2)
        contactactivecheckboxclass1.Updatecnt1(set2);
}
 

All Answers

BalajiRanganathanBalajiRanganathan
Check your trigger on the contact object. it might be calling some future methods.
also you could try to bulkify your future method. (process list of ids instead of single id)
Tejpal KumawatTejpal Kumawat
Please Use a static variable to store the state of the trigger processing.

Follow this url also:

http://appirio.com/category/tech-blog/2009/10/preventing-recursive-future-method-calls-in-salesforce/
Tejpal KumawatTejpal Kumawat
Use these classes :

/***********Class1
public class ProcessorControl {
    public static boolean inFutureContext = false;
}


/***********Class2
//Future class for updating Contact Active Checkbox field
public class contactactivecheckboxclass1 {
    @future
    //Method that takes the contact id as parameter from Trigger and checks if user is active on user Object and updates the related contact accordingly.
    public static void updatecnt1(set<string> x){
        try{
            contact c=[select Is_user_Active__c from Contact where id IN : x limit 1];
            c.Is_User_Active__c=true;
            if(!test.isrunningtest()){
                ProcessorControl.inFutureContext = true;
                database.update(c);
            }
        }
        catch(exception e){
        }
    } 
}

/***********Trigger 
//This is a trigger that is used to check whether the user is active and updates the related Contact
trigger Checkuseractive on User (after insert, after update) {
    set<string> set1 = new set<string>();
    set<string> set2 = new set<string>();
    if (!ProcessorControl.inFutureContext) {
        //Below soql query gets the IsActive and ContactId of the user
        list<user> u=[select id,Isactive,contactid from user where id=:trigger.new];
        for(user usr:u){
            if(usr.IsActive==false)
            {
            set1.add(usr.ContactId);
            }
            else if(usr.IsActive==true)
            {
            set2.add(usr.ContactId);
            }
        }
        //contactactivecheckboxclass.Updatecnt(set1);
        contactactivecheckboxclass1.Updatecnt1(set2);
    }
}
ankushankush
Hi Tejpal,

       Tried the below code using your code given above the contactactivecheckboxclass1 error vanished but now the contactactivecheckboxclass causing the issue. Same issue. Can you please help me in the contactactive checkbox class if I had made any error.



Trigger.

//This is a trigger that is used to check whether the user is active and updates the related Contact
trigger Checkuseractive on User (after insert, after update) {
    set<string> set1 = new set<string>();
    set<string> set2 = new set<string>();
    if (!ProcessorControl.inFutureContext) {
        //Below soql query gets the IsActive and ContactId of the user
        list<user> u=[select id,Isactive,contactid from user where id=:trigger.new];
        for(user usr:u){
            if(usr.IsActive==false)
            {
            set1.add(usr.ContactId);
            }
            else if(usr.IsActive==true)
            {
            set2.add(usr.ContactId);
            }
        }
        contactactivecheckboxclass.Updatecnt(set1);
        contactactivecheckboxclass1.Updatecnt1(set2);
    }
}

Contactactive checkbox class
//Future class for updating Contact Active Checkbox field
public class contactactivecheckboxclass {
    @future
    //Method that takes the contact id as parameter from Trigger and checks if user is active on user Object and updates the related contact accordingly.
    public static void updatecnt(set<string> x){
        try{
            list<contact> cntlist= new list<contact>();
            list<contact> c=[select Is_user_Active__c from Contact where id IN : x limit 1];
            for(contact cnt:c){
            cnt.Is_User_Active__c=false;
            if(!test.isrunningtest()){
                cntlist.add(cnt);
            }
            }
            ProcessorControl.inFutureContext = true;
            database.update(cntlist);
        }
        catch(exception e){
        }
    } 
}

Contact Active checjboxclass1

//Future class for updating Contact Active Checkbox field
public class contactactivecheckboxclass1 {
    @future
    //Method that takes the contact id as parameter from Trigger and checks if user is active on user Object and updates the related contact accordingly.
    public static void updatecnt1(set<string> x){
        try{
            list<contact> cntlist= new list<contact>();
            list<contact> c=[select Is_user_Active__c from Contact where id IN : x limit 1];
            for(contact cnt:c){
            cnt.Is_User_Active__c=true;
            if(!test.isrunningtest()){
                 cntlist.add(cnt);
            }
            }
             ProcessorControl.inFutureContext = true;
            database.update(cntlist);
            }
        
        catch(exception e){
        }
    } 
}

Processor Control Class

public class ProcessorControl {
    public static boolean inFutureContext = false;
}
Tejpal KumawatTejpal Kumawat
Please Check these working fine on my org:

public class ProcessorControl {
    public static boolean inFutureContext = false;
    public static boolean inFutureContext2 = false;
}


public class contactactivecheckboxclass {
    @future
    //Method that takes the contact id as parameter from Trigger and checks if user is active on user Object and updates the related contact accordingly.
    public static void updatecnt(set<string> x){
        try{
            list<contact> cntlist= new list<contact>();
            list<contact> c=[select Is_user_Active__c from Contact where id IN : x limit 1];
            for(contact cnt:c){
            cnt.Is_User_Active__c=false;
            if(!test.isrunningtest()){
                cntlist.add(cnt);
            }
            }
            ProcessorControl.inFutureContext = true;
            database.update(cntlist);
        }
        catch(exception e){
        }
    } 
}


public class contactactivecheckboxclass1 {
    @future
    //Method that takes the contact id as parameter from Trigger and checks if user is active on user Object and updates the related contact accordingly.
    public static void updatecnt1(set<string> x){
        try{
            list<contact> cntlist= new list<contact>();
            list<contact> c=[select Is_user_Active__c from Contact where id IN : x limit 1];
            for(contact cnt:c){
            cnt.Is_User_Active__c=true;
            if(!test.isrunningtest()){
                 cntlist.add(cnt);
            }
            }
             ProcessorControl.inFutureContext2 = true;
            database.update(cntlist);
            }
        
        catch(exception e){
        }
    } 
}

trigger Checkuseractive on User (after insert, after update) {
    set<string> set1 = new set<string>();
    set<string> set2 = new set<string>();
    
    //Below soql query gets the IsActive and ContactId of the user
    //list<user> u=[select id,Isactive,contactid from user where id=:trigger.new];
    for(user usr:trigger.new){
        if(usr.IsActive==false)
        {
        set1.add(usr.ContactId);
        }
        else if(usr.IsActive==true)
        {
        set2.add(usr.ContactId);
        }
    }
    if (!ProcessorControl.inFutureContext) 
        contactactivecheckboxclass.Updatecnt(set1);
    if (!ProcessorControl.inFutureContext2)
        contactactivecheckboxclass1.Updatecnt1(set2);
}
 
This was selected as the best answer
Tejpal KumawatTejpal Kumawat
If above not work in working org then try in new org.

Let me know if it helped !!

PS: If this answers your question then hit Like and mark it as solution!
 
ankushankush
Hi Tejpal part of the code worked I had to use recursive trigger to stop other to fire but you drove me to right path thx for the info.
ankushankush
Ohh did not notice the code you gave me later thx a lot really think this works as well. But I used the one you suggested initially and made slight changes to it. Thanks once again for guiding.
Tejpal KumawatTejpal Kumawat
Good Ankush, Happy to hear :)

PS: If this answers your question then hit Like and mark it as solution!