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
Ian Vianna 2Ian Vianna 2 

I'm getting this error message when trying to update a Metadata. Can you help me?

I'm trying to modify the visibility of a field using Apex, but I'm getting the following error when trying to update Metadata:
MetadataServiceExamples.MetadataServiceExamplesException: Error occured processing component ***.***@***.***.com. In field: fullName - no Profile named ***.***@***.***.com found (INVALID_CROSS_REFERENCE_KEY).


Below is the code for the method that is causing the problem. I have no idea what could be wrong:
public static void updateFLS(String fieldName, Boolean securityLevel) {
        MetadataService.MetadataPort portService = MetadataServiceExamples.createService();
        MetadataService.Profile profileName = new MetadataService.Profile();
        system.debug(profileName.fullName);
        profileName.fullName = UserInfo.getUserName();
        system.debug(profileName.fullName);
        profileName.custom = securityLevel;
        MetadataService.ProfileFieldLevelSecurity fieldSecurity = new MetadataService.ProfileFieldLevelSecurity();
        fieldSecurity.field = fieldName;
        fieldSecurity.editable = true;
        profileName.fieldPermissions = new MetadataService.ProfileFieldLevelSecurity[] {fieldSecurity};
        List <MetadataService.SaveResult> results = portService.updateMetadata(
            new MetadataService.Metadata[] {profileName}
        );
        MetadataServiceExamples.handleSaveResults(results[0]);
}


I am using this API:
https://github.com/financialforcedev/apex-mdapi
Sai PraveenSai Praveen (Salesforce Developers) 
Hi Ian,

I see issue with the below line.UserInfo.GetUserName() only get the user name but not the profile name.
 
profileName.fullName = UserInfo.getUserName();

Can you assign the profile name and check the code.

If this solution helps, Please mark it as best answer.

Thanks,
 
Maharajan CMaharajan C
HI Ian,

You can't directly access the profile full name. It's only available in tooling api. 

For System Administrator the fullname is Admin. Similarly other profiles also having their own full names.

So i have created below apex class to get the profile fullname using tooling api in apex:
 
public class restGetClass {
    public static String restGet(String profilename) {
        
        String pName = profilename;
        if(pName.contains(' ')){
            pName = profilename.replace(' ','+');
        }
        
        system.debug('pName  --> ' + pName  );
        String baseURL = URL.getSalesforceBaseUrl().toExternalForm();
        String endpoint = baseURL+'/services/data/v53.0/tooling/query/?q=SELECT+Id+,+FullName+FROM+Profile+where+Name+=+\''; 
        endpoint = endpoint + pName + '\'';
        HttpRequest req=new HttpRequest(); 
        req.setHeader('Authorization','Bearer '+ UserInfo.getSessionID()); 
        req.setHeader('Content-Type','application/json'); 
        req.setEndpoint(endpoint); 
        req.setMethod('GET'); 
        Http h=new Http(); 
        HttpResponse res =  h.send(req);
        String response=res.getBody();
        system.debug( ' ****** ' + response);
        String profileFullName = '';
        
        if(response.contains('"entityTypeName":"Profile"')){
            JSONParser parser = JSON.createParser(response); 
            while(parser.nextToken()!= null){
                if((parser.getCurrentToken() == JSONToken.FIELD_NAME)&&((parser.getText()=='FullName'))){
                    parser.nextToken(); 
                    profileFullName = parser.getText();
                    system.debug( ' ------- >  ' + (parser.getText()) );
                } 
            } 
        } 
        
        return profileFullName;
    }
}


Update your code like below:
 
MetadataService.MetadataPort portService = MetadataServiceExamples.createService();
MetadataService.Profile profileName = new MetadataService.Profile();

Id profileId = UserInfo.getProfileId();
String profileMetaAPIName = restGetClass.restGet( [Select Id, Name from Profile where Id=:profileId].Name );

profileName.fullName = profileMetaAPIName ;
system.debug(profileName.fullName);
profileName.custom = false;
MetadataService.ProfileFieldLevelSecurity fieldSecurity = new MetadataService.ProfileFieldLevelSecurity();
fieldSecurity.field = 'Account.UpsellOpportunity__c';  // Please change this property as per yours
fieldSecurity.editable = true;
profileName.fieldPermissions = new MetadataService.ProfileFieldLevelSecurity[] {fieldSecurity};
List <MetadataService.SaveResult> results = portService.updateMetadata(
	new MetadataService.Metadata[] {profileName}
);
MetadataServiceExamples.handleSaveResults(results[0]);

One more easy way is there, create custom setting or custom metadata to store the profile name and their respective fullname... But you have to maintain whenever new profiles are coming... Then you can acces easily access inside the apex for refer the profile fullname by just calling metadata or CS match...  Sample is in below screenshot...

User-added image


Thanks,
Maharajan.C