I am new to React Native and am trying to create an app for a charity.
I am having issues when trying to store images taken with the camera in Firebase storage.
The code fragment is below, and looking at the console logs everything looks as I would expect, also below.
The error I get is "imageRef.Putfile is not a function'.
Any help would be greatly appreciated.
CONSOLE LOG OUTPUT
ref, image, imageName breadalert-86646.appspot.com file:///data/user/0/host.exp.exponent/cache/ExperienceData/%2540anonymous%252Frn-complete-guide-10d15822-a070-46a4-a2a0-98550f263c74/ImagePicker/8211188f-6bf4-4aaf-a3ba-e187b1e3707f.jpg CKhLXQlDUtUvKotCYQmJLmOeI1s247
getting storage ref of breadalert-86646.appspot.com
firebaseStorageRef is gs://breadalert-86646.appspot.com/
Image is gs://breadalert-86646.appspot.com/CKhLXQlDUtUvKotCYQmJLmOeI1s247
Image Path is file:///data/user/0/host.exp.exponent/cache/ExperienceData/%2540anonymous%252Frn-complete-guide-10d15822-a070-46a4-a2a0-98550f263c74/ImagePicker/8211188f-6bf4-4aaf-a3ba-e187b1e3707f.jpg
CODE FRAGMENTS
saveImage = (ref, image, imageName, onSuccess, onError) => {
console.log ('ref, image, imageName ' + ref + ' ' + image + ' ' + imageName);
console.log ('getting storage ref of ' + ref);
firebaseStorageRef = firebase.storage().ref();
console.log ('firebaseStorageRef is ' + firebaseStorageRef);
imageRef = firebaseStorageRef.child(imageName);
console.log ('Image is ' + imageRef);
console.log ('Image Path is ' + image);
imageRef.putFile (image.path, {contentType: 'image/jpeg'}).then(function(){
return imageRef.getDownloadURL();
}).then(function(url){
console.log ("Image url", {url:url});
onSuccess(url);
}).catch(function(error){
console.log ("Error while saving the image.. ", error);
onError(error);
});
}
Your imageRef is a Reference type object. Take a look look at the linked API documentation - it has no method called putFile(). That's what the error message is telling you.
If you want to upload a file, you should use the method named put() instead as described in the documentation.
Related
I'm trying to make a basic app to ping an IP. So my HTML form takes one input IP and post it to NodeJS.
I'm using ping module to get the results. it works fine if I enter an IP statically but when I try to get IP by HTML form it just breaks.
This is how my code looks.
app.post("/",function(req,res){
console.log(req.body);
var ip= req.body.ip;
console.log(typeof(ip));
var msg;
var hosts = [ip];
hosts.forEach(function(host){
ping.sys.probe(host, function(isAlive){
console.log(isAlive);
msg = isAlive ? 'host ' + host + ' is alive' : 'host ' + host + ' is dead';
console.log(msg);
});
});
res.write(msg);
res.send();
});
This is what comes on console
The way I see it, this is what is happening:
You issue a ping request. Note, that it takes a callback function as a parameter. This suggests that this is an asynchronous I/O operation.
You execute
res.write(msg);
res.send();
At the time msg is still undefined and therefore I'm guessing that res.write(msg) is in fact the line 30 of app.js file that the error is all about
Only then the callback function is executed, but it's too late
I would recommend changing it as follows
app.post("/",function(req,res){
console.log(req.body);
const ip= req.body.ip;
console.log(typeof(ip));
ping.sys.probe(ip, function(isAlive){
console.log(isAlive);
const msg = isAlive ? 'host ' + host + ' is alive' : 'host ' + host + ' is dead';
console.log(msg);
res.write(msg);
res.send();
});
});
I am currently working on a piece of code that uploads mp4 videos from my localhost onto a server. The basic thing is that if the video is a .mp4 it is directly uploaded, else it is converted to .mp4 and then uploaded. I'm using the video converter using handbrake-js.
All works fine except for a tiny part. When the file isn't that huge, say less than 70-80 Mb, it works like a charm. But the problem is with larger files. Even though I am explicitly calling the res.end / res.send in the .on(end) callback, I receive some blank response in my angular controller, even before the conversion has finished. I have noticed it happens at around 30 to 40% of the conversion. It has a readystate which is equal to XMLHttpRequest.DONE and also status = 200.
Here is the Node side code:
try {
if (fs.existsSync(uploadPath + filename.substring(0, filename.lastIndexOf('.')) + '.mp4')) {
res.end('<b><i>' + filename + '</i></b> already exists in the directory.');
}
else {
const fstream = fs.createWriteStream(path.join(cfg.tempStoragePath, filename));
file.pipe(fstream);
console.log("\nfile_type: " + file_type);
filename = filename.substring(0, filename.lastIndexOf('.'));
// On finish of the copying file to temp location
fstream.on('close', () => {
hbjs.spawn({
input: cfg.tempStoragePath + filename + '.' + file_type,
output: uploadPath + filename + '.mp4'
})
.on('error', err => {
// invalid user input, no video found etc
console.log('error! No input video found at: \n: ' + cfg.tempStoragePath + filename + '.' + file_type);
res.send('Conversion of the file, <b><i>' + filename + '</i></b>, from <b>.' + file_type + '</b>' + ' to <b>.mp4</b> failed because no input video was found at: \n: ' + cfg.tempStoragePath + filename + '.' + file_type);
})
.on('progress', progress => {
progress_percent = (Number(progress.percentComplete) * 2 <= 100) ? Number(progress.percentComplete) * 2 : 100;
eta = progress.eta.split(/[a-zA-Z]/);
minutes = ((+eta[0]) * 60 + (+eta[1])) / 2;
console.log('Percent complete: %d, ETA: %d ///// %s ==> mp4', progress_percent, minutes, file_type);
})
.on('end', end => {
console.log('Conversion from .' + file_type + ' to .mp4 complete.');
//delete the temp file
fs.unlink(cfg.tempStoragePath + filename + '.' + file_type);
let new_path = uploadPath + filename + '.mp4';
let stat = fs.statSync(new_path);
console.log(`Upload of '${filename}' finished`);
if(Number(progress_percent) === Number(100))
res.send('The file, <b><i>' + filename + '</i></b>, has been converted from <b>.' + file_type + '</b>' + ' to <b>.mp4</b> complete.');
})
});
}
}
catch (err) {
res.end(err);
}
Following is part of my angular controller:
request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (request.readyState === XMLHttpRequest.DONE && request.status === 200) {
showConversionModal('<p>' + request.responseText + '</p>', 'done');
}
};
showSomeModal('something');
request.open("POST", client.clientHost + ":" + client.clientPort + "/uploadVideoService");
formData = new FormData();
formData.append("file", files[0], files[0].name);
request.send(formData);
NOTE : All the data which is do a console.log() inside the node is as expected. And even the res.end/send works fine for smaller files which take lesser time. But the problem arises only for those which conversion takes longer than the smaller files.
Also, the if loop which checks for existing file scenario doesn't work as expected for these larger files. I thought at least that should work, because it doesn't even get into the handbrake part. But that is not the case.
And in the browser I get this error:
Failed to load resource: net::ERR_CONNECTION_RESET
which points to the request.send(formData); line, and I have also tried almost all solution from this SO article, with no good effect. But still, the conversion happens fine.
P.S.: Also note that the conversion and upload happens without a problem even for the larger files, it's just the response I'm receiving on the client side that has been my headache.
UPDATE: I tried using the debugger in VS Code, and saw that the breakpoints are rightly hitting the res.end() inside the if loop which checks for existing file scenario, but for some strange reason, the angular controller isn't reacting to it. And this happens only for the larger files.
I figured it out myself after a long time. Turns out there's something like a buffer in Busboy.
Here, I used to link the busboy and express like this:
app.use(busboy());
Just setting the field called highWaterMark to an arbitrary size which would be greater than the file size did the trick.
app.use(busboy({
highWaterMark: 2048 * 1024 * 1024, // Set buffer size in MB
}));
I don't know what might have caused this problem, or what the new field does that solves it, but, it just works is all that I know. It would be helpful if someone could elaborate on this a bit.
I have an EventSource listener on my frontend calling a complicated backend scheme. This code block is written in Typescript.
import * as EventSource from 'eventsource';
private streamData() {
let source = new EventSource('http://localhost:3000/websocket/server/stream');
source.onopen = (e) => {
};
source.onmessage = (e) => {
console.log('id: ' + (<any>e).lastEventId + '; type: ' + e.type + ' data: ' + e.data);
};
}
And I send back the following response to my server :
res.write('id: ' + this.messageId++ + '\n');
res.write('type: message\n');
res.write('data: ' + message + '\n\n');
res.flush();
Now, on the Chrome console, I get all the data needed.
However, on the xhr monitor, I cannot see the EventStream data.
I get the info on my frontend, so this is not a blocking issue for me, but may pose some problems later in debugging.
I had the same issue. The data does not show up when you are using the eventsource polyfill only when you use the built in browser implementation of the EventSource class.
let storage = firebase.storage();
let storageRef = storage.ref("EnglishVideos/" + movieTitle + "/" + movieTitle + "_full.mp4");
console.log(storageRef); // looks OK, no error messages
The above code works, the object returned from Firebase Storage has the correct location, no error messages.
But getDownloadUrl() doesn't work:
let myURL = storageRef.getDownloadUrl();
console.log(myURL); // TypeError: storageRef.getDownloadUrl is not a function
The error is TypeError: storageRef.getDownloadUrl is not a function. It seems like a prototype chain bug. I'm using AngularJS, maybe I didn't inject a necessary dependency into my controller? I injected $firebaseStorage into the controller but it didn't help. My calls to Firebase Realtime Database from this controller are working fine.
It's getDownloadURL, not getDownloadUrl. Capitalization. My working code is
var storageRef = firebase.storage().ref("EnglishVideos/" + movieTitle + "/" + movieTitle + "_full.mp4");
storageRef.getDownloadURL().then(function(url) {
console.log(url);
});
The "official" version is
var storageRef = firebase.storage.ref("folderName/file.jpg");
storageRef.getDownloadURL().then(function(url) {
console.log(url);
});
Note that I needed a () after storage, i.e., storage().
#Thomas David Kehoe's solution got me nearly there.
I was still getting the error:
ERROR TypeError: storageRef.getDownloadURL(...).then is not a function
Here's my solution:
import { Observable } from 'rxjs';
and then inside my function:
var storageRef = this.storage.ref('myFolder/myFile.jpg');
storageRef.getDownloadURL().toPromise().then(function (url) {
console.log(url);
});
In my case, i was trying to call getDownloadURL(); on the upload task i.e
var upload=storage.child(`Testing/abc.png`).put(chosenFile);
//.....
//.....
upload.getDownloadURL();
solved it by doing
var ImgUploadRef=storage.child(`Testing/abc.png`);
var upload = ImgUploadRef.put(chosenFile);
//....
//....
ImgUploadRef.getDownloadURL();
I have a program which respond automatically a sms when receive an income message.
It works when I don't use Sequelize to save data to the database. But when I add the code below, the twiml.message(msg) is never executed.
The problem is when call twiml.message(msg) inside the then it doesn't work. So how to resolve this problem? Thanks
Info.create(param)
.then(info => {
var msg = 'Numero: ' + info.id +
' Nom:' + info.nom +
' Date: ' + info.datesms);
var twiml = new MessagingResponse();
twiml.message(msg);
});