I'm writing an app using react-native and I will build it for both android and iOS.
Anyway, I have been trying to download a ZIP-file using react-native but I can't get it to work. After I have downloaded the file my plan is to unzip it and then store it using AsyncStorage.
But I keep getting the error below:
[RCTNetworking.m:330] Received data was not a string, or was not a recognised encoding.
I have tried various settings for my request but I guess I am simply missing something, the code currently looks like:
fetch('somewhere.path/file.zip', {
method: 'GET',
headers: {
'Accept-Encoding': 'application/zip'
},
})
.then((response) => {
console.log("Success");
})
.catch((error) => {
console.log("Error");
}).done();
Success gets printed but the response data does not contain the zip files data.
If it helps I am debugging using XCode and the simulator.
If anybody has any ideas please help me out! :)
Thanks in advance,
Yon
I also write an app to download some zip files and unzip it. And for download function, I using a plugin called react-native-fetch-blob. Code example:
import RNFetchBlob from 'react-native-fetch-blob';
...
RNFetchBlob.config({
fileCache : true,
path: path + '/file.zip'})
.fetch('GET','http://domain/file.zip')
.progress((received, total) => {console.log('progress', received / total)})
.then((res) => {// the temp file path
console.log('The file saved to ', res.path());
});
...
Thanks,
Related
We are using IOS file upload dialog in order to use video files with our service using react.
All video files are working in android platforms and all browsers in linux and MacOS. However, when we use video files with upload dialog in IOS IPhones such as Iphone 14 Pro Max, then the compress process starts and following that the dialog rejects the video file.
We have been debugging with browserstack using a real phone in a simulator, however no luck until this point.
When we select the file, it firstly runs a compression activity then changes the name of the file to an intermediate file name (as below, the original file name is different), and then upload procedure fails.
Below is the react part which triggers upload mechanism which works with every platform and operating system with exception of IOS.
export const UploadVideo = async (file, signedurl, uploading) =>
{
let resultState = { state: '', data: {} };
if (SERVER_STATUS !== 'localhost')
{
await axios({
method: 'put',
url: signedurl,
data: file,
headers: { 'Content-Type': 'application/octet-stream', },
onUploadProgress: uploading
}).then(function (response)
{
resultState.state = 'success';
}).catch(function (error)
{
resultState.state = 'error';
resultState.data.message = error.message;
window.toastr.error(error.message);
})
} else resultState.state = 'success';
return resultState;
}
The error message I notice here, OS Status error -9806 refers to, according to osstatus.com a secure transport result code. More specifically this one, on Apple's documentation
My take here is that the system is not trusting this URL, I would suggest adding your URL to trusted domains under NSAppTransportSecurity in the Info.plist file. More info on how to do that here.
This is not a solution I would go for for a production app tho, you might want to have a valid certificate for your production URL and app.
Hope this helps.
I'm trying to upload an attachment i get from Outlook to a folder inside a SharePoint document library.
I am Following the docs:
https://learn.microsoft.com/en-us/graph/api/driveitem-put-content?view=graph-rest-1.0&tabs=http#http-request-to-upload-a-new-file
fetch(`https://graph.microsoft.com/v1.0/sites/${siteId}/drive/items/${parentId}:/${attachment.name}:/content`, {
method: 'PUT',
mode: 'cors',
headers: new Headers({
'Authorization': `Bearer ${accesToken}`,
'Content-Type': 'text/plain'
}),
body: attachment.contentBytes
})
All I get is an error with code: -1, Microsoft.SharePoint.Client.InvalidClientQueryException
I've tried setting the body of the fetch request as a simple string such as "hello world" with testing purposes and still get the same error.
Any ideas?
Thx in advance
[EDIT]
I suspect I'm not building the URL right.
I haven't found the documentation for the parameter:
{item-id} I'm assuming this ID is the folder's parentReference.siteId attribute.
Is that right?
Allright, so after some testing with the Microsoft Graph Explorer, I've found that the easiest way to upload a file to a SharePoint folder living inside a document library (distinct to the root document library) is to deal with it as a drive using the endpoint:
/drives/{drive-id}/items/{parent-id}:/{filename}:/content
(https://learn.microsoft.com/en-us/graph/api/driveitem-put-content?view=graph-rest-1.0&tabs=http#http-request-to-upload-a-new-file)
In order to get the document library's drive-id, you can append to the graph query the odata parameter $expand=drive like:
`https://graph.microsoft.com/v1.0/sites/${siteId}/lists?$expand=drive`
Then, alongside other attributes of the targetted document library, you will find the "drive" object, which holds the drive-id associated to the document library you want to upload the file to. So, you would make the PUT request like:
fetch(`https://graph.microsoft.com/v1.0/drives/${libraryDriveId}/items/root:/${folderDisplayName}/${nameOfFile}:/content`, {
method: 'PUT',
mode: 'cors',
headers: new Headers({
'Authorization': `Bearer ${accesToken}`,
'Content-Type': 'text/plain'
}),
body: BINARY_STREAM_OF_DATA
}).then( (response) => {
if (!response.ok) return response.json().then((json) => {throw json});
return response.json();
}).then( (json) => {
//do whatever
}).catch( (err) => {
console.error(err);
})
libraryDriv
libraryDriveId comes from the https://graph.microsoft.com/v1.0/sites/${siteId}/lists?$expand=drive request
/root:/${folderDisplayName} means that the folder you are targetting inside the document library lives under "root:" (the root of the document library) followed by the displayName of the folder you want to upload the file to
nameOfFile is the name of the file you want to upload
I'm using react-native-image-picker (^0.28.0) along with rn-fetch-blob (^0.10.15).
It works so far when using a Simulator, but when I use it on real iPhone, the image isn't uploading, it fails to upload with the following error that is being catched by the promise.
"Error: Could not connect to the server."
(Yes, server is up and running)
If you see this, you might think it's a backend issue but other requests work fine on real device, this one is the only having problems. The image request being sent is this one:
{
data: "RNFetchBlob-file:///var/mobile/Containers/Data/Application/843A96A1-0000-40D3-B50F-95D69B94B87A/tmp/5D22283B-2014-4E9E-AC3E-AE677D91A366.jpg"
filename: "IMG_6834.jpg"
name: "pictures"
type: "image/jpeg"
}
The only difference with the simulator device and my iPhone is the data path. Where on simulator is like "RNFetchBlob-file:///Users/marian-mac/Library/Developer/CoreSimulator/Devices/....etc"
Any idea why should be different from the simulator on this? It seems to be sending the same request.
Some extra info, when I preview the image in an Image component, it shows well too. So it seems the path is correct on the real iPhone.
This is the method to upload image
uploadPicture: function(data, token) {
return RNFetchBlob.fetch('POST', Constants.baseUrl + '/picture', {
Authorization: "Bearer " + token,
'Content-Type': 'multipart/form-data;boundary=***BOUNDARY***'
}, data);
},
And this is how I build the picture request array, this.state.images contains the image-picker data.
this.state.images.forEach((image) => {
reqData.push({
data: image.imageFile,
filename: image.fileName.split('.')[0] + '.jpg',
name: 'pictures',
type: image.type
})
});
The problem could be that you are uploading to a non-https url. Had this same issue and the nsAllowArbitraryLoads made it work on simulator and gave error when using it on a real device.
Had to wait until it became https
It does not seem to be the problem with http or https. (mine is http)
I'm having a file on this path:
filepath =/var/mobile/Containers/Data/Application/F8F06A2A-C04D-4B6D-A316-F879E144366B/Documents/test.wav
I tried RNFetchBlob.wrap(filePath) but no use.
So I tried to add this file to the asset of ios project and using RNFetchBlob.wrap(RNFetchBlob.fs.asset('test.wav')). Voila, it works.
As a result, it seems to be the problem with filepath
I have ejected project of the expo.
After changing info.plist, now I am able to get my app in the list of "open with app list" and actually able to open that file with my expo(React native app).
App.js
Linking.getInitialURL().then((url) => {
if (url) {
console.log(url);
}
}).catch(err => console.error('An error occurred', err));
this code is giving me this URL.
file:///private/var/mobile/Containers/Data/Application/7E55EB55-7C49-4C0C-B4CB-63AC4F49689E/Documents/Inbox/matters-3.csv
So, that means now I have URL of the email attachment, but How am I able to get the data of that csv string in my app?
So I am assuming, when I click open with my app. The URL that is passed into my app from the system is actually a copy of the document that is placed somewhere in our app’s directory.
But when I trying to access this file with Expo.FileSystem. readAsStringAsync it's giving me an error says, the file is not readable.
is there anything to do with storage permission?
Need Help....?
I think you could use react-native-fs. This here should work and print out the contents of the CSV file to the console.
App.js
var RNFS = require('react-native-fs');
Linking.getInitialURL().then((url) => {
if (url) {
RNFS.readFile(url).then((data) => {
console.log(data);
}
}).catch(err => console.error('An error occurred', err));
You can use react-native-fs as Carlo mentioned or rn-fetch-blob, I recommend rn-fetch-blob, to read a file u can check their documentation, it goes something like this
let data = '';
RNFetchBlob.fs.readStream( ...options).then((ifstream) => {
ifstream.open()
ifstream.onData((chunk) => {
data += chunk
// show progress ...%
})
ifstream.onError((err) => {
console.log('oops', err)
})
ifstream.onEnd(() => {
consol.log('final data', data)
})
}))
I have a collection that has references to images, and when the user updates that collection with new images, I want to delete the old images. I am keeping references to the URL for the old images to pass into a function that is written in the cloud code.
I am running all of this local on my computer, however I get the same issue when I run this with the server running on Heroku. This is being called from the iOS SDK.
Here is the function in question:
Parse.Cloud.define('removeOldFilesFromDB', function (request, response) {
var fileUrls = request.params.fileUrls;
var promises = [];
for (var a = 0; a < fileUrls.length; a++) {
promises.push(Parse.Cloud.httpRequest({
method: 'DELETE',
url: fileUrls[a],
headers: {
'X-Parse-Application-Id': process.env.APP_ID || 'myAppId',
'X-Parse-Master-Key': process.env.MASTER_KEY || 'myMasterKey'
}
}));
}
Parse.Promise.when(promises).then( function (result) {
console.log("Successfully deleted files");
response.success(result);
}, function(a,b,c,d,e) {
console.log("Nope jacked it up!");
response.error("Error deleting files");
});
})
When I call the code in question, I don't even see the DELETE request in the parse-server logs at all.
I have the verbose: true flag set in my config, and this is the verbose output to the logs that I get when making this call from the client:
verbose: POST /parse/functions/removeOldFilesFromDB { host: 'e0ae0682.ngrok.io',
'x-parse-client-version': 'i1.12.0',
accept: '*/*',
'x-parse-session-token': 'r:5290c76c47678213770765d990ee38b6',
'x-parse-application-id': 'myAppId',
'x-parse-client-key': 'myClientKey',
'x-parse-installation-id': '3fafc219-1c63-4d68-b42f-5caa3e1c27cb',
'accept-language': 'en-us',
'accept-encoding': 'gzip, deflate',
'x-parse-os-version': '8.1 (12B411)',
'content-type': 'application/json; charset=utf-8',
'content-length': '204',
'user-agent': 'Spin%20the%20Bottle/1 CFNetwork/711.1.12 Darwin/14.0.0',
'x-parse-app-build-version': '1',
'x-parse-app-display-version': '1.0',
'x-forwarded-for': '71.163.238.223' } {
"fileUrls": [
"http://e0ae0682.ngrok.io/parse/files/myAppId/7b5b50e2871af27971be0425f367ab96_file.bin",
"http://e0ae0682.ngrok.io/parse/files/myAppId/cff909602b60b15331b1ac60a4f08697_file.bin"
]
}
Nope jacked it up!
verbose: error: code=141, message=Error deleting files
So it's odd that the DELETE call is not even showing up in there. Am I calling it wrong with the Parse.Cloud.httpRequest method or something?
If I hit the values for fileUrl in my browser, it downloads the images I'm trying to delete so the path is correct.
This is on the latest released version of parse-server, 2.2.10.
These were the instructions that I was following thinking that this is the correct way to do this:
https://parse.com/docs/rest/guide/#files-deleting-files
And this here to make the rest call from the cloud code:
https://parse.com/questions/making-a-rest-call-from-within-cloud-code
According to that, it says I can use Parse.Cloud.httpRequest to make REST calls, so I am not sure what you are referring to as that not the correct ways. Both of those have links to the docs and that is what I followed.
So I am obviously doing something wrong but I am not sure, anyone able to help out?
Just remove myAppId from file URL.
(e.g.)
from
http://e0ae0682.ngrok.io/parse/files/myAppId/7b5b50e2871af27971be0425f367ab96_file.bin
to
http://e0ae0682.ngrok.io/parse/files/7b5b50e2871af27971be0425f367ab96_file.bin