0

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;            
    } 
2
  • 1
    see ContentVersion object doc - I think you need FirstPublishLocationId to be a public library as otherwise it by defaults is a private library.
    – cropredy
    Dec 30, 2019 at 4:28
  • @cropredy You are right, By default it always save to Private library for that salesforce does not allow to create Link record. I created new public Library and pass that Library Id to FirstPublishLocationId and it worked. Thanks Alot. I am updating the code in case someone face same issue. They can refer the working code. Above code in question section is working code. How can i mark this answer as solution ?
    – Sfdc_1184
    Dec 30, 2019 at 5:20

2 Answers 2

1

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]);
2
  • Thanks @cropredy, Passing public Library Id Solved the issue. In my other part of process I am deleting uploaded document from Salesforce in same transaction I believe Deleting ContentDocument will delete uploaded document from all places Anything I need to do in addition to it ?
    – Sfdc_1184
    Dec 31, 2019 at 3:30
  • see this answer
    – cropredy
    Dec 31, 2019 at 6:13
0

Instead of providing a public library id in FirstPublishLocationId field of contentversion object, You can just pass the parentId of the custom object you are trying to associate the file with.

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

Note:- Properties of FirstPublishLocationId is Create, Filter, Group, Nillable, Sort. It means it can be created but not be updated.

This saves you another dml statement and eliminate chunk of lines written for the same purpose.

By default when you do this, Your file will have two contentdocumentlink, One with your user id and another with parentid you have passed.

Another problem you may face in your code is:-

You have passed 'C' as ShareType of contentdocumentlink which is not valid for custom object records. It will give below error:-

System.DmlException: Insert failed. First exception on row 0; first error: INSUFFICIENT_ACCESS_OR_READONLY, Invalid sharing type C: [ShareType]

sharetype C is valid for user object record. ShareType is the permission granted to the user of the shared file in a library.

2
  • Thanks @sanket, I tried passing Custom Object ID to FirstPublishLocationId but it is not linking document with Record. Do i need to create one ContentDocumentLink by passing Record Id ?
    – Sfdc_1184
    Dec 30, 2019 at 20:13
  • @sfdc_1184 what error message you got when you try passing the parent record id to firstpublishlocationid? Dec 31, 2019 at 4:33

You must log in to answer this question.

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