[SalesForce] Retrieve fields under a certain Custom object using Metadata API/Metadata Service class

I have a requirement where we have to retrieve all the fields under an Object say Standard or Custom. I am using FinancialForce Metadata service class. I can Retrieve all the Custom objects and all the Custom fields independently but my requirement is to retrieve only the custom fields only under a certain object. Below code logic is used to retrieve custom objects and fields.

MetadataService.MetadataPort service = createService();
List < MetadataService.ListMetadataQuery > queries = new List < MetadataService.ListMetadataQuery > ();
MetadataService.ListMetadataQuery queryLayout = new MetadataService.ListMetadataQuery();
MetadataService.FileProperties[] fileProperties;
queryLayout.type_x = 'CustomObject';  // 'CustomField'
queries.add(queryLayout);
fileProperties = service.listMetadata(queries, '36.0');

List < String > fullNames = new List < String > ();
if (fileProperties != null) {
    for (MetadataService.FileProperties fileProperty: fileProperties) {
        fullNames.add(fileProperty.fullName);
    }
}
fullNames.sort();  // List of Custom objects/fields


private static MetadataService.MetadataPort createService() {

    MetadataService.MetadataPort service = new MetadataService.MetadataPort();
    service.SessionHeader = new MetadataService.SessionHeader_element();
    service.endpoint_x = //'Org End point';
    service.timeout_x = 120000; //Setting the time out 
    service.SessionHeader.sessionId = // AOauth Access Token
    return service;
}

Please help. Thanks.

Best Answer

Found the answer, I used ReadMetadata of CRUD based calls to get custom field names of certain custom object. Pass the custom object name to below method to get the list of Field names.

public static list < String > readCustomObjectSync(String objectName) {

    //Creating a Service for Callout
    MetadataService.MetadataPort metadataConnection = createService();

    //Checking for namespace
    MetadataService.DescribeMetadataResult describeRes = metadataConnection.describeMetadata('36.0');
    if(describeRes!=null){
        List<MetadataService.DescribeMetadataObject> objectList = describeRes.MetadataObjects;
        String namespace = describeRes.organizationNamespace;

        if(objectName.contains('__c')) {
            if(namespace != null && namespace !='') {
                objectName=namespace+'__'+objectName;
            }
        }
    }

    List <String> objectNames = new List <String>();
    objectNames.add(objectName);

    List <String> fieldName = new List <String>();

    try {
        MetadataService.IReadResult readResult = metadataConnection.readMetadata('CustomObject', objectNames);
        MetadataService.Metadata[] mdInfo = readResult.getRecords();
        System.debug('Number of component info returned: '
                     + mdInfo);
        for (MetadataService.Metadata md : mdInfo) {
            if (md != null) {
                MetadataService.CustomObject obj = (MetadataService.CustomObject) md;
                System.debug('Custom object full name: '+ obj);
                if(obj.fields != null) {
                    for(MetadataService.CustomField field : obj.fields) {
                        if(field != null) {
                            fieldName.add(field.fullName);
                            System.debug('Field Name: ' + field.fullName);
                        }
                    }
                }
            } else {
                System.debug('Empty metadata.');
            }
        }
    } catch (Exception ce) {
        System.debug('exception ' + ce.getMessage());
    }

    return fieldName;
}