4

I am trying to write an Apex Trigger that will change a Checkbox field called Paciente_Senadis__c to TRUE if the Contact record is created within an App called Proyecto_Senadis (DeveloperName: Proyecto_Senadis, Label: Proyecto Senadis, ID: 02u4C0000008tmbQAA), but have not being able to do so.

Here is what I have tried using the AppDefinition Object:

trigger contactoSenadis on Contact (before insert) {
    AppDefinition appInfo = [SELECT Id, Label, DeveloperName FROM AppDefinition LIMIT 1];
    
    for(Contact contactoSenadis : Trigger.new){
        if(appInfo.DeveloperName  == 'Proyecto_Senadis'){
            contactoSenadis.Paciente_Senadis__c = true;
        }
    }
}

And here using the UserAppInfo Object and the App Id:

trigger contactoSenadis on Contact (before insert) {
    UserAppInfo appInfo = [SELECT AppDefinitionId FROM UserAppInfo LIMIT 1];
    
    for(Contact contactoSenadis : Trigger.new){
        if(appInfo.AppDefinitionId  == '02u4C0000008tmbQAA'){
            contactoSenadis.Paciente_Senadis__c = true;
        }
    }
}

After saving the trigger and creating new Contact records, the Paciente_Senadis__c checkbox is still FALSE. What am I missing here? Thanks in advance for your support!

3
  • Can you please check the appInfo.DeveloperName getting the correct value 'Proyecto_Senadis'? Commented Feb 8, 2022 at 20:13
  • 1
    Welcome to Salesforce Stack Exchange (SFSE)! I am unfamiliar with the AppDefinition object, so this might not acually apply... But in your initial AppDefinition query you are limiting it to 1 record. If you have more than one AppDefinition record, you are not guaranteed that it is the one that you want without a WHERE clause.
    – Moonpie
    Commented Feb 8, 2022 at 20:13
  • If you are creating the contact record in "Proyecto_Senadis" app then checkbox will be updating with TRUE Commented Feb 8, 2022 at 20:23

1 Answer 1

6

Both tables that you query contain multiple records.

  • AppDefinition contains 1 record for all of the apps in your org.
  • UserAppInfo contains the latest app used for any user in your org.

So if you put 'LIMIT 1' in your query without a proper WHERE clause which will ensure that you retrieve the exact desired record, the system will return 1 random record from those tables, making it fairly impossible to get a match with the current user.

One other thing to notice here is that there is no 'direct' relationship between UserAppInfo and AppDefinition. The AppDefinitionId on UserAppInfo corresponds to the DurableId field on the AppDefinition (not the Id, which would be expected).

So you can't handle this in 1 SOQL query but actually need both: 1 to find the durableId of the App 1 to find the user's last accessed App (and compare it with the durableId)

So adapt query 1 to fetch only the durableId of the 'Proyecto_Senadis' app:

// fetch the durableId of the app
Id theAppDefinitionId = [SELECT Id, DurableId, Label, DeveloperName FROM AppDefinition WHERE DeveloperName = 'Proyecto_Senadis' LIMIT 1].DurableId;

And adapt query 2 to filter on the current user and the appDefinitionId (and I'd suggest FormFactor as well). I.e.

// fetch the last accessed app by the user (could also be empty so put it in a List)
UserAppInfo[] appInfo = [SELECT AppDefinitionId FROM UserAppInfo WHERE AppDefinitionId = :theAppDefinitionId AND FormFactor = 'Large' AND UserId = :UserInfo.getUserId() LIMIT 1]; 

Then in your code you only check if any UserAppInfo record was found:

if(!appInfo.isEmpty()){
    for(Contact contactSenadis : Trigger.new){ 
        contactSenadis.Paciente_Senadis__c = true; 
    }         
}

No need to check within the loop there, since the app name will be the same across all the trigger context. This prevents you from running that check N times if there are N contacts in the Trigger. Just do it 1 time and then update all the Contacts in the Trigger.

6
  • UserAppInfo has a FormFactor field; it is possible the user could have up to 3 of these UserAppInfo records as a result.
    – sfdcfox
    Commented Feb 8, 2022 at 20:21
  • Good point @sfdcfox. So depending on the requirement (limit this to 1 form factor or include any) we'd need to change either the querying or filtering logic. Commented Feb 8, 2022 at 20:23
  • 1
    +1 Suggested edit: add a clarification after "...put 'LIMIT 1'" that is something like "without a proper WHERE clause which will ensure that you retrieve the exact desired record".
    – Moonpie
    Commented Feb 8, 2022 at 21:19
  • tnx @Moonpie. Suggestion taken over. Commented Feb 8, 2022 at 21:33
  • 1
    Hi @EstebanGonzalez. You are right, I missed the point that the AppDefinition's Id is not in the Id field but in the DurableId field. So you need 2 queries actually. I adapted my answer to this. It should work okay now. Commented Feb 9, 2022 at 8:47

You must log in to answer this question.

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