I am building a Salesforce Community. One of pages has a component that calls a controller action that returns a list of skills (custom ValueLabelModel
class).
I have configured my Community user, assigned some skills, and logged in as him in a different browser. However, the controller action returns a listing of skills and none are identified as selected.
So, I create a new debug log with that user, and once I do, the controller action returns the correct results. If I delete the debug monitor, the results are incorrect again.
I thought perhaps turning on debug somehow changed the user identity, but it doesn't. The contactId
is the same regardless of debug or not debug (I outputted it to the return result to verify).
Here's the full method. Does anyone know why I'd get different results when I have debug enabled vs not?
@AuraEnabled
public static List<ValueLabelModel> getSkills() {
// define list of selectable fields
String[] selectableSkillFields = new String[] { 'Id', 'Name' };
String[] selectableContactSkillFields = new String[] { 'Id', 'Skill__c' };
// check permissions and return accessible fields
selectableSkillFields = CheckReadPermissions(SObjectType.Skill__c, selectableSkillFields);
selectableContactSkillFields = CheckReadPermissions(SObjectType.Contact_Skill__c, selectableContactSkillFields);
// aura enabled view model
List<ValueLabelModel> result = new List<ValueLabelModel>();
// get the contact id from the the user's record
String contactId = [select ContactId from user where id = :UserInfo.getUserId() limit 1][0].ContactId;
System.debug('Contact: ' + contactId);
// get all the skills
List<Skill__c> skills = Database.query('select ' + String.join(selectableSkillFields, ',') + ' from Skill__c order by Name');
// get the selected stills ids
List<Contact_Skill__c> selectedSkills = Database.query('select ' + String.join(selectableContactSkillFields, ',') + ' from Contact_Skill__c where Contact__c = :contactId');
// build the skill id list
List<String> selectedSkillIds = new List<String>();
for(Contact_Skill__c cs : selectedSkills) selectedSkillIds.add(cs.Skill__c);
// prepare the result
for(Skill__c skill : skills) {
if(selectedSkillIds.contains(skill.Id)) {
System.debug('Selected: ' + skill.Name);
result.add(new ValueLabelModel(skill.Id, skill.Name, true));
} else {
System.debug('Not Selected: ' + skill.Name);
result.add(new ValueLabelModel(skill.Id, skill.Name));
}
}
return result;
}
I hard coded the contactId
to the Community user's ID, which I have been testing with, but the debug strangeness still happens. Only when I am debugging this user/contact will the proper select skills be returned from the query.
I also have a strange permission problem related to the same object, which might be related to this issue since they are both involve the Contact_Skill__c
custom object.
I opened a case with Salesforce regarding this issue, but they shut it down without resolution since my client doesn't have premium support and they can't look at the code.
I don't think the issue lies within the code logic, but I'd appreciate it if someone could review my code and tell me if my code might return different results if the user Community User is being debugged at the time.
It's been weeks since posting this problem, and Salesforce can't help and I took another look at it today. I painstakingly debugged a user using System.assert
in unit tests I wrote for it and what I saw was astounding.
I found that Salesforce would inconsistently return false
on List.contains()
when I proved that the List contained the items I was looking for. Here are actual debug printouts from Salesforce when it was running false:
selectedSkills[0].Skill__c: a0c1F000000IZ0rQAG
skills[0].Id: a0c1F000000IZ0rQAG
skills1.Id: a0c1F000000IZ0sQAGselectedSkillIds[0]: a0c1F000000IZ0rQAG
selectedSkillIds.contains('a0c1F000000IZ0rQAG'): false selectedSkillIds.contains('a0c1F000000IZ0sQAG'): false
I bolded the matching strings. Even though selectedSkillIds
contained a0c1F000000IZ0rQAG
it still returned false.
This is where it gets weird. I recreated a simple contains test in Developer Console, and the contains
method worked correctly.
I reran my test again and amazingly, the contains
method worked correctly in the test. I made no changes to the code/login and I got different results. The only thing I did was run a code snippet in Developer Console to very List.contains
was working as I expect.
Here's the output again with it working (again, bolded where matched):
selectedSkills[0].Skill__c: a0c1F000000IZ1GQAW
skills[0].Id: a0c1F000000IZ1GQAW
skills1.Id: a0c1F000000IZ1HQAWselectedSkillIds[0]: a0c1F000000IZ1GQAW
selectedSkillIds.contains('a0c1F000000IZ1GQAW'): true selectedSkillIds.contains('a0c1F000000IZ1HQAW'): false
This last bit of testing I did not enable debugging because I am using a newly created user for running the tests the a Community profile. The user only exists in the context of the test.
But I now see that when I ran my Developer Console snippet, Salesforce automatically created a 30 mins debug session for me. So my original theory is correct, the code responds differently (specifically List.contains
) when being run under the context as a debugged user. To prove this, I deleted the DEBUG session for my login, and the tests failed.
System.debug()
shows the same results.