[SalesForce] Error While uploading document to File(Contentversion,ContentDocument) In visualforce

I was using Attachment to upload file and link to custom object record in my visualforce page but now moving logic from Attachment to file and linking uploaded file to custom object record(parentsId). While debugging the i can see contentVersion and contentDocument record inserted successfully but record is getting linked to User by default but I want document to link with Custom object Record (parentId)

Error :

failed to insert ContentDocument.{errors:{fields:'ContentDocumentId', message:'You cannot create a link for a document in a private library: ContentDocument ID', statusCode:'FIELD_INTEGRITY_EXCEPTION', }, id:null, success:'false', }

    function uploadAttachment(filecontent, filename, filetype, parentId, description) {
        var attachment         = new sforce.SObject('ContentVersion');
        debugger;
        attachment.Title        = getFileName(filename);
        attachment.PathOnClient = getFileName(filename);;
        attachment.FirstPublishLocationId  = '0582f0000008jddAAA'; => Id of 
 Public Library (This is Imp else you will not be able to create new Link record)
        attachment.VersionData = filecontent;
        attachment.ContentLocation = 'S';
        debugger;
        attachment.Description = getDesc(description);
        debugger;
        var result =  sforce.connection.create([attachment]);
        console.log('Record Inserted++11 ++',result[0]);

        debugger;

        var soqlQuery = "Select Id,ContentDocumentId FROM ContentVersion where Id='"+ result[0].id +"'"; 
        var opps = sforce.connection.query(soqlQuery).getArray('records'); 
        var resultVesrion = opps[0];
        var ContentDocId  = resultVesrion.ContentDocumentId;

        var conDoc = new sforce.SObject('ContentDocumentLink');
        conDoc.ContentDocumentId=ContentDocId;
        conDoc.LinkedEntityId = parentId;
        conDoc.ShareType = 'C';
        conDoc.Visibility = 'AllUsers';
        debugger;
        var result1 = sforce.connection.create([conDoc]); 
        console.log(conDoc);
        if (result1[0].getBoolean("success")) {
            console.log("ContentDocument.with id " + result1[0].id + " inserted");
        } else {
            console.log("failed to insert ContentDocument." + result1[0]);
        }

        return result;            
    } 

Best Answer

By default, a ContentVersion is added to a private library and when attempting to link an object to the newly-created ContentDocument you will get the error in your Post. Use the code below that defines the library as per ContentVersion object documentation

FirstPublishLocationId
Create, Filter, Group, Nillable, Sort

Description

ID of the location where the version was first published. If the version is first published into a user's personal library or My Files, the field will contain the ID of the user who owns the personal library or My Files. In Lightning Experience, if the first version is published into a public library, the field will contain the ID of that library.

Accepts all record IDs supported by ContentDocumentLink (anything a file can be attached to, like records and groups).

Setting FirstPublishLocationId allows you to create a file and share it with an initial record/group in a single transaction, and have the option to create more links to share the file with other records or groups later. When a file is created, it’s automatically linked to the record, and PublishStatus will change to Public from Pending/Personal.

This field is only set the first time a version is published via the API. FirstPublishLocationId can’t be set to another ID when a new content version is inserted.

attachment.Title        = getFileName(filename);
attachment.PathOnClient = getFileName(filename);
attachment.FirstPublishLocationId  = somePublicLibraryId; 
attachment.VersionData = filecontent;
attachment.ContentLocation = 'S';
attachment.Description = getDesc(description);
var result =  sforce.connection.create([attachment]);