Hi,
First of all thanks for creating this plugin. I have integrated this plugin and now the thing is I want to upload PDF file to Dropbox as well as Google Drive.
I am able to get access token. But not able to upload pdf file to google drive or Dropbox. I know I am missing some steps. Below is my code that I have implemented.
REQUEST :-
RNFetchBlob.fetch('POST', 'https://www.googleapis.com/upload/drive/v3?uploadType=media', {
Authorization : user.accessToken,
'data': JSON.stringify({
path : "http://xyz.com/" + this.state.pdf,
mode : 'add',
autorename : true,
mute : false
}),
'Content-Type' : 'application/pdf',
})
.then((res) => {
console.log("response in success " + JSON.stringify(res));
})
.catch((err) => {
console.log("response in error " + JSON.stringify(err));
// error handling ..
})
It will give below response inside success.
RESPONSE :-
response in success {"data":"Not Found","taskId":"njehngge5xm4hl33iynfog","type":"utf8","respInfo":{"respType":"","headers":{"alt-svc":"hq=\":443\"; ma=2592000; quic=51303432; quic=51303431; quic=51303339; quic=51303335,quic=\":443\"; ma=2592000; v=\"42,41,39,35\"","server":"UploadServer","date":"Fri, 23 Mar 2018 06:50:13 GMT","content-length":"9","content-type":"text/html; charset=UTF-8","vary":"X-Origin","x-guploader-uploadid":"AEnB2UrlSTCFYVYabN_dzHqqr55dBKjosk8u0IQ3D4bcysJyp_KkaYSW4yrE2P4gziHgfKOUrZpfAxaSpBwV6D4-a0142hiYhA"},"redirects":["https://www.googleapis.com/upload/drive/v3?uploadType=media"],"timeout":false,"taskId":"njehngge5xm4hl33iynfog","state":"2","status":404,"rnfbEncode":"utf8"}}
Pleas help. I am stuck in this from past few days. Let me know if this is not sufficient information for you.
Thanks
Hi @singhlovey ,
First of all, if you are using the simple upload from google drive rest,
https://developers.google.com/drive/v3/web/simple-upload
the url for post request is incorrect, a '/files' is missing, if you compare it with, the multipart link,
https://developers.google.com/drive/v3/web/multipart-upload
It's a mistake on the google docs end, and the correct link should be,
'https://www.googleapis.com/upload/drive/v3/files?uploadType=media'
I have tested it and it works alright.
Next the required headers for google drive upload are not correct, the ones in your request are only for dropbox, so you should try the above with this url,
'https://content.dropboxapi.com/2/files/upload' as mentioned in the example of react-native-fetch-blob docs, and the content-type should be 'application/octet-stream', as mentioned there.
RNFetchBlob.fetch('POST', 'https://content.dropboxapi.com/2/files/upload', {
// dropbox upload headers
Authorization : "Bearer access-token...",
'Dropbox-API-Arg': JSON.stringify({
path : '/img-from-react-native.png',
mode : 'add',
autorename : true,
mute : false
}),
'Content-Type' : 'application/octet-stream',
// Change BASE64 encoded data to a file path with prefix `RNFetchBlob-file://`.
// Or simply wrap the file path with RNFetchBlob.wrap().
}, RNFetchBlob.wrap(PATH_TO_THE_FILE))
.then((res) => {
console.log(res.text())
})
.catch((err) => {
// error handling ..
})
and where is your RNFetchBlob.wrap(PATH_TO_THE_FILE), the data to your file.
Okay and back to the google drive thing,
dont forget to add, 'Content-Length' header as mentioned there and wrap your file as above, modify the url as I mentioned first, and you will be good to go!
@harzkr
Thanks for your reply.
Okay I have done the changes as mentioned above but i am not understanding which file path I need to pass under 'path' property of an object and for PATH_TO_THE_FILE.
Here I am passing file path which exists under my project's folder.
I am little bit confused here. can you please clarify which should be the correct file path?
Thanks
@singhlovey
Okay so for the dropbox api, the path property of the object, inside JSON.stringify, is the path in which the uploaded file gets stored at within the dropbox folder system. So in the above case, it gets stored as the png file under the root/home directory of dropbox, if you were to give a value,
'/folder1/folder2/img-from-react-native.png' , it will get stored in folder2 inside folder1 etc etc.
And as you mention, yes, the PATH_TO_THE_FILE, is the path of the stored file inside your project. It may be in /content/com.projectname/ or /data/data/.. or from external storage,
you might want to have a look at this link from the wiki docs,
https://github.com/wkh237/react-native-fetch-blob/wiki/File-System-Access-API
for a complete idea of the file and directory system.(Please be careful while visiting the link, the project has been shifted, so make sure it's exactly the above, with wkh237, copy and paste it rather than clicking it)
Well do remember that the path in JSON.stringify is ONLY for dropbox api, there is NO 'data' part for google drive.
I hope I was clear and you'd be able to resolve the issue!
@harzkr
I have made the changes as per your suggestions.
Now my code look like as shown below.
RNFS.readDir(RNFS.DocumentDirectoryPath)
.then((result) => {
console.log('GOT RESULT', JSON.stringify(result));
RNFetchBlob.fetch('POST', 'https://www.googleapis.com/upload/drive/v3/files?uploadType=media',{
Authorization : String(user.accessToken),
'Content-Type' : 'application/octet-stream',
'Content-Length' : result[1].size
}, "RNFetchBlob-file://" + RNFS.DocumentDirectoryPath + '/demo.pdf')
.then((res) => {
console.log("response in success" + res.text())
})
.catch((err) => {
console.log("response in error" + err)
})
.then((contents) => {
// log the file contents
console.log(contents);
})
.catch((err) => {
console.log(err.message, err.code);
});
But now I got error :- RNFetchBlob request error: TypeError: expected dynamic type string', but had typeint64'null
NOTE:- I am using react-native-fs plugin to fetch path of storage files.
Please let me know where I am wrong?
@singhlovey
I think the problem is with the result[1].size, it should be a string and not an integer.
And though there is nothing particularly wrong with your method, just to be sure, that the right headers are passed, you can make the content length and other variables string before you call the function, and call the function stand-alone,
For example in your code,
//new line
var func = this
RNFS.readDir(RNFS.DocumentDirectoryPath)
.then((result) => {
console.log('GOT RESULT', JSON.stringify(result));
//new lines
func.setState({
size:result.size.toString(),
})
.then((contents) => {
// log the file contents
console.log(contents);
})
.catch((err) => {
console.log(err.message, err.code);
});
And call this function later, just be sure that the state has updated,
RNFetchBlob.fetch('POST', 'https://www.googleapis.com/upload/drive/v3/filesuploadType=media',{
Authorization : String(user.accessToken),
'Content-Type' : 'application/octet-stream',
'Content-Length' : this.state.size
}, "RNFetchBlob-file://" + RNFS.DocumentDirectoryPath + '/demo.pdf')
.then((res) => {
console.log("response in success" + res.text())
})
.catch((err) => {
console.log("response in error" + err)
})
That should work
@harzkr
Many thanks to you!!!
I have modify some code and It works :)
QUERY :- How can I set pdf file name. currently it shows untitled.
NOTE:- I have tried to add like this also [{name : 'demo', filename : 'demo.pdf', data : RNFetchBlob.wrap(RNFS.DocumentDirectoryPath + '/demo.pdf')}] but still giving me untitled name.
One more thing. I have done this for google drive. Now I want to do the same for dropbox. can you suggest any react native plugin for dropbox login or authentication so that I can get access token of dropbox?
or how to authenticate user with dropbox in react native to upload file to dropbox as well?
Thanks
@singhlovey
That's wonderful you got it working and you are welcome.
Well coming to authenticating with dropbox api, since I haven't been using it in any case scenarios, I do not have an idea of the packages that might be available for react native for the same.
However, you can check out auth0 it self, it's pretty reliable, darn easy to set up, is free for a limited time,
but does come at a price for regular usage. Here are some links, you might want to look at.
https://auth0.com/authenticate/react-native/dropbox/
https://auth0.com/pricing
But the best I'll say is to directly use the dropbox api itself, which you must have seen here,
https://www.dropbox.com/developers/documentation/http/documentation
Right at the beginning itself under 'Authorization', they have provided everything you will need for authorization, make a GET request at, with your parameters created at the app dashboard at Dropbox,
(more info on everything about setting up here https://www.dropbox.com/developers/reference/oauth-guide )
https://www.dropbox.com/oauth2/authorize
You will get a response object like this [REDIRECT_URI]?code=ABCDEFG&state=[STATE]
Then call this url with a POST request with the above code( all descriptions in the docs), and you will get your bearer token.
https://api.dropboxapi.com/oauth2/token
That should take care of the authentication, and as I mentioned I haven't used dropbox api, but the instructions on the docs are pretty simple and achieve the results in a straightforward manner.
Hope that helps!
@harzkr
Thanks. I will try and get back to you if any problem.
QUERY :- How can I set pdf file name. currently it shows untitled.
NOTE:- I have tried to add like this also [{name : 'demo', filename : 'demo.pdf', data : RNFetchBlob.wrap(RNFS.DocumentDirectoryPath + '/demo.pdf')}] but still giving me untitled name. How to set meaningful pdf file name?
Thanks
Hey Hi @singhlovey
I saw your edited comment now, which you have asked above,
Yeah the simple upload request for google drive is only for the file and not for any metadata, so no format will work which will upload the name to the file through that url.
You can see more here https://developers.google.com/drive/v3/reference/files/create
where two separate urls are given for file upload and uploading the metadata separately.
So there is resumable and multipart uploads, which you can check here,
https://developers.google.com/drive/v3/web/multipart-upload
https://developers.google.com/drive/v3/web/resumable-upload
Both of them have direct sending of the metadata, but the body part of the request is a bit muddled up, you would have to create the multipart body exactly as specified there(and it does become a problem sometimes)
Here are a few links discussing the metadata issue, you can have a look,
https://stackoverflow.com/questions/41492692/upload-and-name-a-file-using-google-drive-rest-api-v3-and-angular-2
https://stackoverflow.com/questions/10317638/how-do-i-add-create-insert-files-to-google-drive-through-the-api/10323612#10323612
They mainly achieve it using the drive file api from googleapis, you can check out the drive.files.create
from the API explorer here https://developers.google.com/apis-explorer/#p/
So basically there are a lot of options, but the simplest one( according to me), which I use,
is the updating of file, https://developers.google.com/drive/v3/reference/files/update
I post a request to https://www.googleapis.com/drive/v3/files with a json file with my name, mimetype. content etc., and then get the fileid from there , and then update the fileid with the patch request to
https://www.googleapis.com/upload/drive/v3/files/fileId , with my contents, and there you will have it,
I am posting my code below for your reference, my use case is an audio/aac file upload.
//read the file and get the size, name etc. and set them in state variables
var func = this
const res = await fetch('https://www.googleapis.com/drive/v3/files', {
method: 'POST',
headers: {
'Authorization': auth,
'Content-Type':'application/json'
},
body:JSON.stringify({
"name": func.state.name,"mimeType": "audio/aac","description": "Stuff about the file"
}),
})
const json = await res.json()
console.log(json)
func.setState({
fileiden:json.id
}, function(){
RNFetchBlob.fetch('PATCH',`https://www.googleapis.com/upload/drive/v3/files/${func.state.fileiden}`,{
'Authorization' : auth,
'Content-Type' : 'audio/aac',
'Content-Length':func.state.size.toString()
},RNFetchBlob.wrap(func.state.target))
.then((res) => {
console.log("response",res.json())
})
.catch((err) => {
console.log("error",err)
})
})
You can get the job done, through any of the methods above, hope I was clear, if not, do ask me
This issue seems to have been resolved and inactive. Closing due to inactivity.
I use the same method to get the id from the file as above :
``
fetch('https://www.googleapis.com/drive/v3/files', {
method: 'POST',
headers: {
"Authorization" :Bearer ${this.state.accesToken}`,
'Content-Type':'application/json'
},
body:JSON.stringify({
"name": file.fileName,"mimeType": file.type
})
}).then((response)=>{
console.log(response.status)
if(response.status === 200){
return response.json();
}else{
this.setState({isUploading:false})
}
}).then((responseJson)=>{
console.log(responseJson)
if(responseJson.id ){
console.log(responseJson.id)
}
}).catch((err)=>{
console.log(err)
});
```
but i get 401. Any idea how to resolve this @harzkr
Hey Hi @uendar
It has been a while since I used the API, though on checking out the errors page for google drive API, it seems your credentials are incorrect, 401, and in general it is the response for invalid authorisation.
Have a look at their page maybe it will help you resolve this.

Most helpful comment
Hey Hi @singhlovey
I saw your edited comment now, which you have asked above,
Yeah the simple upload request for google drive is only for the file and not for any metadata, so no format will work which will upload the name to the file through that url.
You can see more here https://developers.google.com/drive/v3/reference/files/create
where two separate urls are given for file upload and uploading the metadata separately.
So there is resumable and multipart uploads, which you can check here,
https://developers.google.com/drive/v3/web/multipart-upload
https://developers.google.com/drive/v3/web/resumable-upload
Both of them have direct sending of the metadata, but the body part of the request is a bit muddled up, you would have to create the multipart body exactly as specified there(and it does become a problem sometimes)
Here are a few links discussing the metadata issue, you can have a look,
https://stackoverflow.com/questions/41492692/upload-and-name-a-file-using-google-drive-rest-api-v3-and-angular-2
https://stackoverflow.com/questions/10317638/how-do-i-add-create-insert-files-to-google-drive-through-the-api/10323612#10323612
They mainly achieve it using the drive file api from googleapis, you can check out the
drive.files.createfrom the API explorer here https://developers.google.com/apis-explorer/#p/
So basically there are a lot of options, but the simplest one( according to me), which I use,
is the updating of file, https://developers.google.com/drive/v3/reference/files/update
I post a request to
https://www.googleapis.com/drive/v3/fileswith a json file with my name, mimetype. content etc., and then get the fileid from there , and then update the fileid with the patch request tohttps://www.googleapis.com/upload/drive/v3/files/fileId, with my contents, and there you will have it,I am posting my code below for your reference, my use case is an audio/aac file upload.
You can get the job done, through any of the methods above, hope I was clear, if not, do ask me