I am working on a React project and I am using the Cordova plug-in for the first time. I have it taking pictures correctly but now I want to store them locally on the device using persistent storage. I found pretty good documentation but for some reason cannot get this code to work. If anyone could help I would really appreciate it!
Here is my function:
takePicture() {
navigator.camera.getPicture(
imageData => {
this.setState({image: imageData});
let path = 'filesystem:' + imageData;
window.resolveLocalFileSystemURL(
path,
(entry) => {
window.requestFileSystem(
LocalFileSystem.PERSISTENT,
50 * 1024 * 1024,
(fileSys) => {
//The folder is created if doesn't exist
fileSys.root.getDirectory(
'Observation Photos',
{create:true, exclusive: false},
directory => {
let d = new Date(),
n = d.getTime(),
filename = n + '.jpg';
entry.moveTo(directory, filename, (entry) => {
Photos.insert(entry);
}, handleError);
},
handleError
);
},
handleError
);
}, (error) => {
console.log(error);
}
);
}, message => {
console.log(message);
}
);
}
Here is an example of the paths I am passing in:
filesystem:file:///storage/emulated/0/Android/data/com.id1b9kkvri4mj2dnqkf9p/cache/1470171102308.jpg
Returns this in the inspector:
FileError {code: 5}
value of Path should be Android/data/com.id1b9kkvri4mj2dnqkf9p/cache/1470171102308.jpg;
so it needs a small change:
let path = imageData.replace("file:///storage/emulated/0/","");
Related
im making a whatsapp bot, im saving the chats in a excel file (im using exceljs) to read and handle some responses, i prefer to use promises and resolve them, i have a function to read chats:
const readChat = (number, message, step = null) =>
new Promise((resolve, reject) => {
setTimeout(() => {
number = number.replace("#c.us", "");
number = `${number}#c.us`;
const pathExcel = `./chats/${number}.xlsx`;
const workbook = new ExcelJS.Workbook();
const today = moment().format("DD-MM-YYYY hh:mm");
if (fs.existsSync(pathExcel)) {
const workbook = new ExcelJS.Workbook();
workbook.xlsx
.readFile(pathExcel)
.then(() => {
const worksheet = workbook.getWorksheet(1);
const lastRow = worksheet.lastRow;
let getRowInsert = worksheet.getRow(++lastRow.number);
getRowInsert.getCell("A").value = today;
getRowInsert.getCell("B").value = message;
if (step) {
getRowInsert.getCell("C").value = step;
}
getRowInsert.commit();
workbook.xlsx
.writeFile(pathExcel)
.then(() => {
const getRowPrevStep = worksheet.getRow(lastRow.number);
const lastStep = getRowPrevStep.getCell("C").value;
resolve(lastStep);
})
.catch((err) => {
console.log("ERR", err);
reject("error");
});
})
.catch((err) => {
console.log("ERR", err);
reject("error");
});
} else {
const worksheet = workbook.addWorksheet("Chats");
worksheet.columns = [
{ header: "Fecha", key: "number_customer" },
{ header: "Mensajes", key: "message" },
{ header: "Paso", key: "step" },
];
step = step || "";
worksheet.addRow([today, message, step]);
workbook.xlsx
.writeFile(pathExcel)
.then(() => {
resolve("STEP_1");
})
.catch((err) => {
console.log("Error", err);
reject("error");
});
}
}, 1000);
});
but the code after that else, its giving me the error: ERR Error: End of data reached (data length = 0, asked index = 4). Corrupted zip ?, the else, is supposed to be executed when there is no excel saved with that chat. I searched in many questions and pages, but i have not found any solution
I believe you would get this error after you stop your execution in between, i.e when the file is getting updated and this would corrupt the excel file.
You could try adding a "try catch" around read file in your if condition and create a new copy of workbook whenever you get these particular errors ('End of data reached (data length = 0, asked index = 4). Corrupted zip ?' or 'File not found:')
I've faced the same issue on frontend, in my case the file was corrupted. Try open it in excel.
I'm using elasticsearch search engine with my react app, I was reading one file at the backend as you see in the code and it work perfectly, but now I want to read three different JSON files to three different indexes using the "fs" package and bulk request, can you please help me?
the code:
// Start reading the json file
fs.readFile("DocRes.json", { encoding: "utf-8" }, function (err, data) {
if (err) {
throw err;
}
// Build up a giant bulk request for elasticsearch.
bulk_request = data.split("\n").reduce(function (bulk_request, line) {
var obj, ncar;
try {
obj = JSON.parse(line);
} catch (e) {
console.log("Done reading 1");
return bulk_request;
}
// Rework the data slightly
ncar = {
id: obj.id,
name: obj.name,
summary: obj.summary,
image: obj.image,
approvetool: obj.approvetool,
num: obj.num,
date: obj.date,
};
bulk_request.push({
index: { _index: "ncar_index", _type: "ncar", _id: ncar.id },
});
bulk_request.push(ncar);
return bulk_request;
}, []);
// A little voodoo to simulate synchronous insert
var busy = false;
var callback = function (err, resp) {
if (err) {
console.log(err);
}
busy = false;
};
// Recursively whittle away at bulk_request, 1000 at a time.
var perhaps_insert = function () {
if (!busy) {
busy = true;
client.bulk(
{
body: bulk_request.slice(0, 1000),
},
callback
);
bulk_request = bulk_request.slice(1000);
console.log(bulk_request.length);
}
if (bulk_request.length > 0) {
setTimeout(perhaps_insert, 100);
} else {
console.log("Inserted all records.");
}
};
perhaps_insert();
});
You can create multiple promises for each file read and feed it to the elastic search bulk_request.
const fsPromises = require('fs').promises,
files = ['filename1', 'filename1'],
response = [];
const fetchFile = async (filename) => {
return new Promise((resolve, reject) => {
const path = path.join(__dirname, filename);
try {
const data = await fsPromises.readFile(path)); // make sure path is correct
resolve(data);
} catch (e) {
reject(e)
}
});
files.forEach((fileName) => results.push(fetchFile()));
Promise.all(results).then(data => console.log(data)).catch(e => console.log(e));
}
Once you get data from all the promises pass it to the elastic search.
Good day all, Please I have this code below for testing download speed, and has been working for some time now. But recently always bring this error and doesn't work any more. Please help look into it.
Thanks
Tried with this url: 'https://drive.google.com/open?id=1MBHJXeRxMLLwHFpqbgTdEPsFArMM0cz7'
[Error: Unable to resolve host "drive.google.com": No address associated with hostname]
Tried with this url: 'https://upload.wikimedia.org/wikipedia/commons/b/b9/Pizigani_1367_Chart_1MB.jpg'
[Error: Unable to resolve host "upload.wikimedia.org": No address associated with hostname]
const downloadSizeInBits = 12000000;
const metric = 'MBps';
export const measureConnectionSpeed = (imageURIParam: string): any => {
const imageURI = imageURIParam
? imageURIParam
: 'https://drive.google.com/open?id=1MBHJXeRxMLLwHFpqbgTdEPsFArMM0cz7';
return new Promise((resolve, reject) => {
const startTime = new Date().getTime();
RNFetchBlob.config({
fileCache: false,
})
.fetch('GET', imageURI, {})
.then((res) => {
const endTime = new Date().getTime();
const duration = (endTime - startTime) / 1000;
const speed = downloadSizeInBits / (1024 * 1024 * duration);
resolve({metric, speed});
})
.catch(reject);
});
};
//Called from here in another component
getDownloadSpeed = async () => {
try {
const networkSpeed = await measureConnectionSpeed();
this.setState({value: networkSpeed.speed});
return networkSpeed.speed;
} catch (error) {
//handle error
ToastAndroid.show(
'Network Issues, unable to get download speed',
ToastAndroid.LONG,
);
console.log(error);
}
};
Thanks
Tim
Heyy, i am trying to upload a cropped image to firebase.
I would prefer to use the ionic native "image-picker" and "Crop".
I really dont know how to upload the image after cropping it, because it only returns the path of the new image.
I have already tryed something like this. This worked, but i was not able to crop the image. But as i mentioned, i would prefer using the native tools anyways.
export interface UploadData {
name: string;
filepath: string;
size: number;
}
uploadFile(event: FileList) {
// The File object
const file = event.item(0);
// Validation for Images Only
if (file.type.split('/')[0] !== 'image') {
console.error('unsupported file');
return;
}
// The storage path
const path = `whatever/${new Date().getTime()}_${file.name}`;
// File reference
const fileRef = this.storage.ref(path);
// The main task
this.task = this.storage.upload(path, file, { customMetadata });
this.snapshot = this.task.snapshotChanges().pipe(
finalize(() => {
// Get uploaded file storage path
this.UploadedFileURL = fileRef.getDownloadURL();
this.UploadedFileURL.subscribe(resp => {
this.addImagetoDB({
name: file.name,
filepath: resp,
size: this.fileSize
});
}, error => {
console.error(error);
});
}),
tap(snap => {
this.fileSize = snap.totalBytes;
})
);
}
addImagetoDB(image: UploadData) {
const id = this.db.createId();
// Set document id with value in database
this.imageCollection.doc(id).set(image).then(resp => {
console.log(resp);
}).catch(error => {
console.log('error ' + error);
});
}
}
This is how i would like to do it. But i really have no idea, how to upload it at this point.
pickImage() {
this.imagePicker.getPictures(this.imagePickerOptions).then((results)
=> {
// tslint:disable-next-line: prefer-for-of
for (let i = 0; i < results.length; i++) {
this.cropImage(results[i]);
}
}, (err) => {
alert(err);
});
}
cropImage(imgPath) {
this.crop.crop(imgPath, { quality: 50 })
.then(
newPath => {
// ?????
},
error => {
alert('Error cropping image' + error);
}
);
}
Sorry, i am very new to this stuff.
Thanks for your help :)
It seems that you might be able to do this without the crop feature being needed.
These are the options according to the docs:
options = {
// Android only. Max images to be selected, defaults to 15. If this is set to 1, upon
// selection of a single image, the plugin will return it.
maximumImagesCount: int,
// max width and height to allow the images to be. Will keep aspect
// ratio no matter what. So if both are 800, the returned image
// will be at most 800 pixels wide and 800 pixels tall. If the width is
// 800 and height 0 the image will be 800 pixels wide if the source
// is at least that wide.
width: int,
height: int,
// quality of resized image, defaults to 100
quality: int (0-100),
// output type, defaults to FILE_URIs.
// available options are
// window.imagePicker.OutputType.FILE_URI (0) or
// window.imagePicker.OutputType.BASE64_STRING (1)
outputType: int
};
So you could use:
options = {
maximumImagesCount: 3,
width: 800,
height: 600,
quality: 50,
outputType: 1
};
From what I've been researching you could then put the image into Firebase Storage using:
storageRef.putString("Your base64 string substring variable", 'base64');
I'm not sure if this is enough to get you fixed up but I thought I would post what I had found anyway.
I just tried this, but it dosnĀ“t work too. I have no idea why...
constructor(private imagePicker: ImagePicker, private crop: Crop,
private file: File) {
let storageDb = firebase.storage();
this.storageRef = storageDb.ref();
}
pickImage() {
this.imagePicker.getPictures(this.imagePickerOptions).then((results)
=> {
// tslint:disable-next-line: prefer-for-of
for (let i = 0; i < results.length; i++) {
this.cropImage(results[i]);
}
}, (err) => {
alert(err);
});
}
cropImage(imgPath) {
this.crop.crop(imgPath, { quality: 50 })
.then(
newPath => {
try {
let n = newPath.lastIndexOf("/");
let x = newPath.lastIndexOf("g");
let nameFile = newPath.substring(n + 1, x + 1);
this.file.readAsArrayBuffer(newPath, nameFile).then((res) => {
let blob = new Blob([res], { type: "image/jpeg" });
var uploadTask = this.storageRef.child('images/' + this.event.id).put(blob);
uploadTask.on('state_changed', (snapshot) => {
let url = uploadTask.snapshot.downloadURL;
this.croppedImagepath = url;
}, (error) => {
alert("error: " + error);
}, () => {
alert("uploaded");
let url = uploadTask.snapshot.downloadURL;
this.croppedImagepath = url;
})
})
}
catch (z) {
alert('error beim erstellen des blobs' + z);
}
},
error => {
alert('Error cropping image' + error);
}
);
}
this.file.dataDirectory was showing null, I have installed cordova in globally but still, I am not able to find any solution.where did I make a mistake?
download() {
const fileTransfer: FileTransferObject = this.transfer.create();
const url = 'http://www.example.com/file.pdf';
fileTransfer.download(url, this.file.dataDirectory + 'file.pdf').then((entry) => {
console.log('download complete: ' + entry.toURL());
}, (error) => {
// handle error
});
}
use
cordova.file.dataDirectory
instead of
this.file.dataDirectory