You need to sign in to do that
Don't have an account?
Download Content from Saleforce using Salesforce mobile SDK and Phonegap
We are developing a mobile app using salesforce mobile sdk for android(and ios too) and phonegap. This requires downloading Salesforce Content(Content can be a file of any type/extension) directly and saving it into mobile device.
We tried below url which exposes the content of the Salesforce Content document.
https://salesforce.com/services/data/v23.0/sobjects/ContentVersion/06890000000wo1zAAA/VersionData.
Since the above url doesnt allow direct download of file, we are parsing the content and writing it into a file to save in mobile device.
//This function is invoked when download link is clicked and dwnldDocParams contains saleforce content record id and filename
function downloadFileToDevice(dwnldDocParams){
var dwnldDocId = dwnldDocParams.substring(0,18);
var fileNameWithExt = dwnldDocParams.substring(18);
forcetkClient.getContentData(dwnldDocId, onSuccessContentData, onErrorSfContentData);
}
forcetk.Client.prototype.getContentData = function(recordId, callback, error) {
var query = '/' + this.apiVersion + '/sobjects/ContentVersion/'+recordId+'/VersionData'
this.ajaxForContent(query, callback, error);
}
forcetk.Client.prototype.ajaxForContent = function(path, callback, error, method, payload, retry) {
var that = this;
var url = this.instanceUrl + '/services/data' + path;
//This is the sample url
//https://salesforce.com/services/data/v23.0/sobjects/ContentVersion/06890000000wo1zAAA/VersionData
$j.ajax({
type: method || "GET",
async: this.asyncAjax,
url: (this.proxyUrl !== null) ? this.proxyUrl: url,
contentType: 'application/octetstream', //since the response sent by salesforce has Content-type : application/octetstream for content of any type(text,image,docx..)
cache: false,
processData: false,
data: payload,
success: callback,
error: (!this.refreshToken || retry ) ? error : function(jqXHR, textStatus, errorThrown) {
if (jqXHR.status === 401) {
that.refreshAccessToken(function(oauthResponse) {
that.setSessionToken(oauthResponse.access_token, null,
oauthResponse.instance_url);
that.ajaxForContent(path, callback, error, method, payload, true);
},
error);
} else {
error(jqXHR, textStatus, errorThrown);
}
},
dataType: "text", //valid datatypes are text,json,xml,html,jsonp
beforeSend: function(xhr) {
if (that.proxyUrl !== null) {
xhr.setRequestHeader('SalesforceProxy-Endpoint', url);
}
xhr.setRequestHeader(that.authzHeader, "Bearer " + that.sessionId);
xhr.setRequestHeader('X-User-Agent', 'salesforce-toolkit-rest-javascript/' + that.apiVersion);
if (that.userAgentString !== null) {
xhr.setRequestHeader('User-Agent',that.userAgentString);
}
}
});
}
//Success callback function
function onSuccessContentData(response) {
var $j = jQuery.noConflict();
//Phonegap method
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,
function (fileSystem) {
//fileSystem.root.getFile("readme.txt", {create: true, exclusive: false}, //here file name is hardcoded just for static verification for writing into files of different types
fileSystem.root.getFile("testimage.png", {create: true, exclusive: false},
//fileSystem.root.getFile("sampleDoc.docx", {create: true, exclusive: false},
function (fileEntry) {
fileEntry.createWriter(
function gotFileWriter(writer) {
writer.onwrite = function(evt) {
console.log("write success");
};
writer.write(response);
}, fail);
}, fail);
}, fail);
}
The above code works only for text files. For text files response is text only.For other files, we could observe Though we could get response for files of other types also and write into file in device, they could not be viewed. May be the response sent as octetstream need to processed in some way before writing into file. Dont know if there is any issue writing binary data into file using above phonegap function. Any pointers to successfully write content into file (of any type) is really helpful.
Sample response obtained for an image(png) file:
07-18 15:11:10.822: D/CordovaLog(1421): >onSuccessContentData:response--"?PNG\r\n\u001a\n\u0000\u0000\u0000\rIHDR\u0000\u0000\u0000 \u0000\u0000\u0000?\b\u0002\u0000\u0000\u0000\u0005?v?\u0000\u0000\u0000\u0019tEXtSoftware\u0000Adobe ImageReadyq?e<\u0000\u0000\u0000?IDATx???1\u0012?0\u0010\u0005Pp????\n?86\u0014R?\u0006?`?\u0001,?\u0005\u0016_.??o\"Yp?????.?\u0012\nt\u0000?z??D;?(?\u001e?/?M>?K\u0013??n???\t6???\t\u0016?\u0013?\u0003?\u0004{'???g??'pL?\"??\u001e?;?RJl?5?c,0MS??1??\u0001\u0000\u0000\u0000\u0000r\\??s?a\u0018r??\u000f\u0000\u0000\u0000\u0000\u0000 Kgw???E\u0000\u0000\u0000\u0000\u0000\u0000\u0000[4^??\"S?\u0007\u0000?E?A?$P\"\tN?,??\u0018?>@\u0002C?J$???#??\u0004??\u0004???3?4c????\u0001\u0000\u0000\u0000\u0000?\u0004\b\u001f?v?\u0003\u0000\u0000\u0000\u0000\u0000\u0000|?\u0007?B?\u0019?|??\u0000\u0000\u0000\u0000IEND?B`?"
It would be really great if there is any way to download the file directly from salesforce instead of reading response and writing manually into a file in device.
I could find another url which DIRECTLY DOWNLOADS THE FILE if we are currently in salesforce session. I tried this url in place of url in above scenario but no progress..
https://<instance>content.force.com/sfc/servlet.shepherd/version/download/<ContentVerion record Id>
Eg: https://c.ap1.content.force.com/sfc/servlet.shepherd/version/download/06890000000CZjT.