Error in react native "`filePath` expects a string value" - javascript

I have some code to open the camera with React Native and save the image using FireBase, but it gives me an error saying filePath expects a string value.
Here is my code:
const openCamera = ()=>{
launchCamera({quality:0.5},(fileobj) =>{
console.log(fileobj)
const uploadTask = storage().ref().child(`/items/${Date.now()}`).putFile(fileobj.uri)
uploadTask.on('state_changed',
(snapshot) => {
var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
if (progress == 100){alert("Uploaded")}
},
(error) => {
alert("something went wrong")
},
() => {
uploadTask.snapshot.ref.getDownloadURL().then((downloadURL) =>{
console.log(downloadURL)
setImage(downloadURL)
});
}
);
})
}

The launchCamera method accepts a callback that will be called with a response object. This response object has four keys; didCancel, errorCode, errorMessage, and assets.
assets is an array of the selected media, so you'll need to grab the first one.
const openCamera = () => {
launchCamera({ quality: 0.5 }, (result) => {
if (result.errorCode || result.didCancel) {
return console.log('You should handle errors or user cancellation!');
}
const img = result.assets[0];
const uploadTask = storage()
.ref()
.child(`/items/${Date.now()}`)
.putFile(img.uri);
uploadTask.on(
'state_changed',
(snapshot) => {
var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
if (progress == 100) {
alert('Uploaded');
}
},
(error) => {
alert('something went wrong');
},
() => {
uploadTask.snapshot.ref.getDownloadURL().then((downloadURL) => {
console.log(downloadURL);
setImage(downloadURL);
});
},
);
});
};

I saw your problem and I have a solution for you .
I don't know why but please try to use like this once :
fileobj.assets[0].uri

Related

Save Firebase download URL in hook array

I use Firebase Storage with React. I have an array with multiple images. For every single image in it I do an upload to Firebase. Once I get the downloadUrl back, I want to store it in a hook array for further use. However, my array is always empty. Why ?
If I use the useEffect hook as soon as the array changes, I get an output every time the downloadUrl is inserted into the array. However: One line per URL and not an array with the URLs
const [uploadBilder, setUploadBilder] = useState([]);
await Promise.all(
mehrBilder?.map((bild) => {
const storageRef = ref(
storage,
`${aktuellerUser._id}/artikelBilder/` + bild.name
);
const uploadTask = uploadBytesResumable(storageRef, bild);
uploadTask.on(
"state_changed",
(snapshot) => {
const progress =
(snapshot.bytesTransferred / snapshot.totalBytes) * 100;
console.log("Upload is " + progress + "% done");
switch (snapshot.state) {
case "paused":
console.log("Upload is paused");
break;
case "running":
console.log("Upload is running");
break;
}
},
(error) => {
console.log(error);
},
() => {
getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
setUploadBilder((prev) => [...prev, downloadURL]);
console.log(uploadBilder); //EMPTY
});
}
);
})
);
useEffect(() => {
console.log(uploadBilder) //count 3 = right!
},[uploadBilder]}

Can't find variable: getDownloadURL in react native firebase

I have copied and pasted code from the firebase documentation itself, still I am getting this error:
WARN Possible Unhandled Promise Rejection (id: 0):
ReferenceError: Can't find variable: getDownloadURL
import storage from "#react-native-firebase/storage";
const pickImageAndUpload = async () => {
try {
launchImageLibrary({
quality: 0.5
}, (fileobj) => {
console.log(fileobj.assets[0].uri);
const uploadTask = storage().ref().child(`/userprofile/${Date.now()}`).putFile(String(fileobj.assets[0].uri))
uploadTask.on('state_changed',
(snapshot) => {
const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
if (progress == 100) alert('image uploaded')
},
(error) => {
// Handle unsuccessful uploads
alert('error uploading image')
},
() => {
getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
setImage(downloadURL)
});
}
);
})
} catch (err) {
alert(err)
console.log(err);
}
}
I don't know why this error is coming, I have searched everywhere, this error does not occur in any other person code, please help me
You can check the official documentation here
If you are using React Native Firebase then getDownloadURL() is a method on StorageReference and not a function (like in Modular SDK). Try refactoring the code as shown below:
const storageRef = storage().ref().child(`/userprofile/${Date.now()}`)
const uploadTask = storageRef.putFile(String(fileobj.assets[0].uri))
uploadTask.on('state_changed', (snapshot) => {
const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
if (progress == 100) alert('image uploaded')
}, (error) => {
// Handle unsuccessful uploads
alert('error uploading image')
}, () => {
storageRef.getDownloadURL().then((downloadURL) => {
setImage(downloadURL)
});
});

Cannot get data out of composable to fetch firebase data

I have a composable in vue that uploads data to firebase storage. It works, but I cannot get the data out of the composable. I think it has something to do with a return or where I'm defining terms?
The code below is built around the documentation available for firebase Storage (https://firebase.google.com/docs/storage/web/upload-files).
useStorage.js
import { ref } from "vue";
import { projectStorage } from "../firebase/config";
import {
uploadBytesResumable,
getDownloadURL,
ref as storageRef,
} from "#firebase/storage";
const useStorage = () => {
const error = ref(null);
const url = ref(null);
const filePath = ref(null);
const uploadImage = async (file) => {
filePath.value = `images/${file.name}`;
const storageReference = storageRef(projectStorage,
filePath.value);
const uploadTask =
uploadBytesResumable(storageReference, file);
await uploadTask.on(
"state_changed",
(snapshot) => {
const progress =
(snapshot.bytesTransferred / snapshot.totalBytes)
* 100;
console.log("Upload is " + progress + "% done");
},
(err) => {
console.log(err);
error.value = err.message;
},
() => {
getDownloadURL(uploadTask.snapshot.ref).then((downloadURL)
=> {
console.log("File available at", downloadURL);
url.value = downloadURL;
console.log(url.value); <--HAS CORRECT VALUE
return url.value; <--DOESNT DO ANYTHING
});
}
);
console.log(url.value);
};
return { url, filePath, error, uploadImage }; <--URL IS
NOT RETURNING OUT OF THIS COMPOSABLE
};
export default useStorage;
A simpeler approach would be to await getDownloadUrl: url.value = await getDownloadURL(uploadTask.snapshot.ref). Then, you can get rid of the .then on that function. Right now, return url.value is assigned to nothing.
Warning: Also write some sort of catch - in case something would go wrong - in a production environment.

Error of 'TypeError: storage.ref is not a function

Here is the buttonUploadClicked function, and I have imported firebasestorage as const storage = firebase.storage; But still the error is there
This function is run when a button is clicked and error shows only when the button is clicked
Code is below
const handleUpload = () => {
var imageName = Math.random(0, 10000) * Math.random(0, 100);
if (image) {
const uploadTask = storage.ref(`images/${imageName}.jpg`).put(image);
uploadTask.on(
'state_changed',
(snapshot) => {
// progress function beta
const progressP = Math.round((snapshot.bytesTransferred / snapshot.totalBytes) * 100);
setProgress(progressP);
},
(error) => {
console.log(error);
},
() => {
storage
.ref('images')
.child(`${imageName}.jpg`)
.getDownloadURL()
.then((imageUrl) => {
db.collection('posts').add({
timestamp: firebase.firestore.FieldValue.serverTimestamp(),
caption: caption,
photoUrl: imageUrl,
username: user.email.replace('#gmail.com', '').replace('.', ''),
picUrl: user.photoURL,
});
});
},
);
}
};
Try to replace
const storage = firebase.storage;
by
const storage = firebase.storage();
The "()" should do the trick - you need no reference to "firebase.storage" itself, but to that what is "produced" by it.

Issues while uploading an image to firebase storage with Antd upload action

I'm using antd picture-wall/card example to upload images to my firebase storage with this reference code and the only place I'm changing is action property on <Upload> component.
On the action property, I'm using a function that uploads the images to firebase storage instead of a link both are accepted as seen in docs.
My action function looks like this;
export async function uploadImage(file) {
const storage = firebase.storage()
const metadata = {
contentType: 'image/jpeg'
}
const storageRef = await storage.ref()
const imageName = generateHashName() //a unique name for the image
const imgFile = storageRef.child(`Vince Wear/${imageName}.png`)
return imgFile.put(file, metadata)
}
Issue comes, The image uploads to firebase successfully, but I keep getting antd response handling errors and possibly not sure what action function should return, even though, is written in the docs that it should return a promise.
Error message:
XML Parsing Error: syntax error
Location: http://localhost:3000/[object%20Object]
Line Number 1, Column 1:
Errors also appear as a red border on the uploaded image thumbnail.
Requested help, What should my action function return to get rid of errors. I can parse my firebase response and return the necessary details to antd upload action.
Using
"antd": "^3.9.2",
"firebase": "^5.8.5",
"react": "^16.7.0",
You can use customRequest prop to fix this issue. Have a look
class CustomUpload extends Component {
state = { loading: false, imageUrl: '' };
handleChange = (info) => {
if (info.file.status === 'uploading') {
this.setState({ loading: true });
return;
}
if (info.file.status === 'done') {
getBase64(info.file.originFileObj, imageUrl => this.setState({
imageUrl,
loading: false
}));
}
};
beforeUpload = (file) => {
const isImage = file.type.indexOf('image/') === 0;
if (!isImage) {
AntMessage.error('You can only upload image file!');
}
// You can remove this validation if you want
const isLt5M = file.size / 1024 / 1024 < 5;
if (!isLt5M) {
AntMessage.error('Image must smaller than 5MB!');
}
return isImage && isLt5M;
};
customUpload = ({ onError, onSuccess, file }) => {
const storage = firebase.storage();
const metadata = {
contentType: 'image/jpeg'
}
const storageRef = await storage.ref();
const imageName = generateHashName(); //a unique name for the image
const imgFile = storageRef.child(`Vince Wear/${imageName}.png`);
try {
const image = await imgFile.put(file, metadata);
onSuccess(null, image);
} catch(e) {
onError(e);
}
};
render () {
const { loading, imageUrl } = this.state;
const uploadButton = (
<div>
<Icon type={loading ? 'loading' : 'plus'} />
<div className="ant-upload-text">Upload</div>
</div>
);
return (
<div>
<Upload
name="avatar"
listType="picture-card"
className="avatar-uploader"
beforeUpload={this.beforeUpload}
onChange={this.handleChange}
customRequest={this.customUpload}
>
{imageUrl ? <img src={imageUrl} alt="avatar" /> : uploadButton}
</Upload>
</div>
);
}
}
Just leaving this here incase anyone wanted to track the progress of the file aswell
const customUpload = async ({ onError, onSuccess, file, onProgress }) => {
let fileId = uuidv4()
const fileRef = stg.ref('demo').child(fileId)
try {
const image = fileRef.put(file, { customMetadata: { uploadedBy: myName, fileName: file.name } })
image.on(
'state_changed',
(snap) => onProgress({ percent: (snap.bytesTransferred / snap.totalBytes) * 100 }),
(err) => onError(err),
() => onSuccess(null, image.metadata_)
)
} catch (e) {
onError(e)
}
}

Categories