I've been testing out a component where one can programmatically create a field in the user object. It's being used to allow a user to check a few boxes that'll filter components in pages (using the lightning page component filtering) that is unique to that user.

With this test I've met an annoying problem. If I manually create the field, it's all good because we get to decide the field level access. But when I create it programmatically it comes with zero access to any users even my own (sys admin).

The way I'm creating the field is:

global with sharing class FieldGen {
        //@future(callout = true)
        global static void makeCreateUserFieldCallout(String intendedName){
            String objectapiname = 'User';
        /* assertFieldName just makes name acceptable for the API name of the field. */
        String fieldapiname = TogglerCtrlApex.assertFieldName(intendedName, true);
        String fieldlabel = TogglerCtrlApex.assertFieldName(intendedName, false);
        String fielddescription = 'Field created for topic visibility toggler component!';
            HttpRequest requestinside = new HttpRequest();
            requestinside.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionID());
            requestinside.setHeader('Content-Type', 'application/json');
            String fieldDef = '{"Metadata" : ';
            String metadef = '"type" : "Checkbox","description" : "'+fielddescription+'","defaultValue":"true", "inlineHelpText" : "","precision" : null,"label" : "'+fieldlabel+'","required" : false';
            fieldDef += '{'+metadef+'},';
            fieldDef += '"FullName" : "'+objectapiname+'.'+fieldapiname+'"}';
            Http http = new Http();
            HTTPResponse res = http.send(requestinside);
        catch(Exception e){

Basically using the API to create a field in the User Object. Unfortunatelly it doesn't give access though =/

I've been experimenting with the MetadataService class to try to add field permissions to a permission set when the field is created. This isn't working though and the documentation for this class is very slim. This is what I have so far:

public with sharing class MetadataServiceExamples
    @future(callout = true)
    public static void testPerm()
        /* Find the Quick Toggler Permission Set! */
        MetadataService.MetadataPort service = createService();
        String[] permissionSetNames = new String[] {'Quick_Visibility_Toggler_Permissions'};
        List<MetadataService.PermissionSet> perm = 
            (List<MetadataService.PermissionSet>) service.readMetadata('PermissionSet', permissionSetNames).getRecords();
        MetadataService.PermissionSet quickPerm = perm.get(0);
        System.debug('Test: ' + quickPerm.fieldPermissions);
        MetadataService.PermissionSetFieldPermissions fieldSec = new MetadataService.PermissionSetFieldPermissions();
        quickPerm.fieldPermissions.add(fieldSec);// = new MetadataService.PermissionSetFieldPermissions[] {fieldSec} ;
        System.debug('Test: ' + quickPerm.fieldPermissions);
        List<MetadataService.SaveResult> results =
                new MetadataService.Metadata[] { quickPerm });
        System.debug('Results: ' + results);

It seems I can't access and change the permission set though. WIth that being said, does anyone know of a way I could either add CRUD permissions for the new field to a permission set or a profile programmatically right after the field is created?


Based on the best answer I just added this method to the class and it adds permissions to a permission set:

    public static void addToPermissionSet(String fieldName){
        String fieldAPIName = assertFieldName(fieldName, true); /* this just makes sure theres's an __c in the input. */
        /* Get Id of permission Set and build API name of field. */
        PermissionSet ps = [SELECT Id,Name FROM PermissionSet WHERE Name = 'Example' LIMIT 1];
        String fullAPIName = 'User.'+fieldAPIName; /* Example: User.TestMe__c */
        System.debug('FullAPI:' + fullAPIName);
        FieldPermissions newPerm = new FieldPermissions();
        newPerm.Field = fullAPIName;
        newPerm.ParentId = ps.Id;
        newPerm.PermissionsEdit = true;
        newPerm.PermissionsRead = true;
        newPerm.SobjectType = 'User';
        Insert newPerm; 
  • Hey Victor, can I know how your complete code looks like now? I want to know if you go with Metadata service or the above REST. Thanks. Sep 10, 2022 at 1:06
  • 1
    Hey @LetMeCodeYou, done! Sep 27, 2022 at 8:17

1 Answer 1


You can Provide Field Permission to permission set by creating FieldPermissions record like this

FieldPermissions fp= new FieldPermissions();
fp.Field='Case.AccountId';//the name of new field
fp.ParentId='0PS0o000001WP6AGAW';// id of permission set 
Insert fp; 

though this only works for permission set here is the link for object https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_fieldpermissions.htm

  • This is incredibly helpful! Let me test it out and I'll mark it as answered if it works, thank you so much even for the reply, I did not know this obj existed :) Apr 12, 2021 at 15:04

You must log in to answer this question.

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