Error 400 Bad Request while Uploading Image to firebase storage in React Native - reactjs

I am working on react native project connected to firebase. I am =using firebase storage ad=nd trying to upload a file to firebase storage But I get following error.
{code: 400, message: "Bad Request. Could not access bucket quickbuy-a0764.appspot.com","status":"Access_Bucket"}
I tried configuring my permissions but did not work for me.
example of Image Uri I am providing to put() is as follows
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAk and so on
Now what should I do to resolve this issue?
let filename = values.images + Date.now();
let uri = values.images[0];
const uploadTask = storage.ref(`images/${filename}`).put(uri);
uploadTask.on("state_changed", (snapshot) => {
console.log(snapshot);
});

firebase.storage.Reference#put() accepts a Blob, Uint8Array or an ArrayBuffer. Because you are trying to upload a Data URI, which is a string, you need to use [firebase.storage.Reference#putString()`](https://firebase.google.com/docs/reference/js/firebase.storage.Reference#putstring).
To do this for a data URI, you would use:
someStorageRef.putString(uri, firebase.storage.StringFormat.DATA_URL);
Next, based on these lines:
const filename = values.images + Date.now();
let uri = values.images[0];
values.images is an array, which means that filename will end up being something similar to "[object Object],[object Object]1620528961143".
As I covered in this answer on your question yesterday, this is a poor way to generate IDs as it can lead to duplicates & collisions - use a Push ID instead.
const uri = /* ... */;
const rootRef = firebase.database().ref();
const filename = rootRef.push().key;
const uploadTask = storage.ref(`images/${filename}`)
.putString(uri, firebase.storage.StringFormat.DATA_URL);
uploadTask.on("state_changed", (snapshot) => {
console.log(snapshot);
});

Future Use with Version 9 of the SDK
import { getStorage, ref, uploadBytes } from "firebase/storage";
const uploadImage = async (values) => {
const filename = values.images + Date.now();
const uri = values.images[0];
// Create a root reference
const storage = getStorage();
// Create a reference to 'images/$filename.jpg'
const filesImagesRef = ref(storage, 1images/${filename}.jpg);
await uploadBytes(filesImagesRef, uri).then((snapshot) => {
console.log('Uploaded a blob or file!');
});
}
Let us know how this works for you!

Related

ObjectId id not of Function Type

https://i.stack.imgur.com/7Tq6v.png
import {MongoClient, ObjectId} from "mongodb";
async function handler(req, res){
if(req.method === "POST"){
const data = req.body;
const client = await MongoClient.connect("mongoDB URL")
const db = client.db();
const postItCollection = db.collection("postIts");
const result = await postItCollection.updateOne({_id: ObjectId(data.id)}, {$set:{positionX:data.y, positionY:data.x}});
console.log(result);
client.close();
res.status(201).json({message:"success"})
}
}
export default handler;
I'm attaching a picture just in case.
I've been looking for it for three hours, but I can't find the answer....
I don't think there's anyone on Earth who has the same problem as me....
I tried installed the "bson-objectid" library.
and "mongoose" Types property
import mongoose from "mongoose";
const { ObjectId } = mongoose.Types;
I've tried it, but I've seen same error of "method expression is not of function type"
Help me, all the masters of the earth.
From Newbie.
import {MongoClient, ObjectId} from "mongodb";
async function handler(req, res){
if(req.method === "POST"){
const data = req.body;
const client = await MongoClient.connect("mongoDB URL")
const db = client.db();
const postItCollection = db.collection("postIts");
const result = await postItCollection.updateOne({_id: data.id}, {$set:{positionX:data.y, positionY:data.x}}); // <= if i not use ObjectId
console.log(result);
client.close();
res.status(201).json({message:"success"})
}
}
export default handler;
if I not use ObjectId I've got success messages but can't find id...
https://i.stack.imgur.com/XJOQH.png
I just want to find id in mongoDB and change data
PS. How can I see the image right away instead of the URL?
I looked at the other answers and did the same thing, but only the URL came out...
Oh i find Answer...!
It's new operation...
How do I search for an object by its ObjectId in the mongo console?
const result = await postItCollection.updateOne({_id: new ObjectId(data.id)}, {$set:{positionX:data.y, positionY:data.x}});

How to upload SVG images on firebase storage?

I am having issue to upload an SVG image to firebase storage.
The upload seems to work correctly how when I am trying to click on the link. It returns the error file empty as per screenshot below.
Please see below my upload function
import { getStorage, ref, uploadBytesResumable, getDownloadURL } from "firebase/storage"
export const uploadToFirebase = async (file) => {
const storage = getStorage()
const storageRef = ref(storage, "images/avatar.svg")
const metadata = {
contentType: "image/svg+xml",
}
const uploadTask = uploadBytesResumable(storageRef, file, metadata)
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) => {
// A full list of error codes is available at
// https://firebase.google.com/docs/storage/web/handle-errors
switch (error.code) {
case "storage/unauthorized":
// User doesn't have permission to access the object
break
case "storage/canceled":
// User canceled the upload
break
// ...
case "storage/unknown":
// Unknown error occurred, inspect error.serverResponse
break
}
},
() => {
// Upload completed successfully, now we can get the download URL
getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
console.log("File available at", downloadURL)
})
}
)
}
i am calling this function in my home component as fellow
useEffect(() => {
uploadToFirebase("../public/avatar.svg")
}, [])
Can someone help me underytand what is wrong with my code,please?
You pass a String to your uploadToFirebase() method which results in calling the uploadBytesResumable() method with a String as second argument.
As explained in the doc (above link), this second argument shall be a Blob, a Uint8Array or an ArrayBuffer.
Following our below comments: I'm not verse in reactjs but you need to get the image from your public folder as a Blob Object (or as a File Object, which is "a specific kind of Blob") and pass it to your uploadToFirebase() method. The following SO question & answers give several ways to do that (untested).

Uploading image to azure blob storage using React

I am trying to upload image from react to azure blob storage but the request fails with error :
TypeError: Cannot read properties of undefined (reading 'size')
at BlockBlobClient.uploadFile
here is a sample of code trying to achieve it :
import { BlobServiceClient } from '#azure/storage-blob';
const account = process.env.REACT_APP_AZURE_ACCOUNT_NAME;
const sas = process.env.REACT_APP_SAS_TOKEN;
const containerName = 'usercontainer';
const blobServiceClient = new BlobServiceClient(
`https://${account}.blob.core.windows.net/?${sas}`,
);
export const uploadToBlob = async (file) => {
const containerClient = blobServiceClient.getContainerClient(containerName);
const blobName = file.src + new Date().getTime();
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
const uploadBlobResponse = await blockBlobClient.uploadFile(file.src);
console.log(
`Upload block blob ${blobName} successfully`,
uploadBlobResponse.requestId,
);
};
There are a few issues here:
You are calling uploadFile method which is only available in NodeJS runtime and is not available in the browser. Please see documentation of this method here: https://learn.microsoft.com/en-us/javascript/api/#azure/storage-blob/blockblobclient?view=azure-node-latest##azure-storage-blob-blockblobclient-uploadfile.
The method you would want to use is uploadData which expects an object of type Blob. Considering you have a data URL, you would need to create a Blob object out of it. Please see this question regarding converting a data URL to Blob: Blob from DataURL?

Send FormData object and File in a single Axios POST request

I currently have a Spring boot API controller method (below) that accepts an object as well as a MultiPart file. I am able to successfully send a POST request via Postman however I am now struggling to make this post request via my front-end ReactJS application using Axios.
#PostMapping(
path = "/upload",
consumes = {
MediaType.APPLICATION_JSON_VALUE,
MediaType.MULTIPART_FORM_DATA_VALUE
},
headers = {
"Content-Type=multipart/form-data"
}
)
public SoundProfile uploadSoundProfile(Authentication auth,
#RequestPart("soundProfileRequest") SoundProfileRequest soundProfileRequest,
#RequestPart("audio_file") MultipartFile audio_file){
return soundProfileService.uploadSoundProfile(auth, soundProfileRequest, audio_file);
}
Postman POST request:
The following is my service method to process the object and file which is responsible for saving the object to a MySQL database and then storing the file in an Amazon S3 bucket.
public SoundProfile uploadSoundProfile(Authentication auth, SoundProfileRequest soundProfileRequest, MultipartFile audio_file) {
if (audio_file.isEmpty()){
throw new IllegalStateException("no audio file received");
}
AppUser current_user = appUserRepository.findByEmail(auth.getName())
.orElseThrow(
() -> new IllegalStateException("User not found")
);
Map<String, String> metadata = new HashMap<>();
metadata.put("Content-Type", audio_file.getContentType());
metadata.put("Content-Length", String.valueOf(audio_file.getSize()));
String soundPath = UUID.randomUUID().toString();
SoundProfile soundProfile = new SoundProfile(
soundPath, // SoundPath = S3 key
soundProfileRequest.getCaseBrand(),
soundProfileRequest.getCaseModel(),
soundProfileRequest.getSwitches(),
soundProfileRequest.getKeycaps(),
soundProfileRequest.getStabilizers(),
soundProfileRequest.getLube(),
soundProfileRequest.getMods(),
current_user
);
// save sound profile to database
soundProfileRepository.save(soundProfile);
String path = String.format("%s/%s", BucketName.KEYBOARD_AUDIO_BUCKET.getBucketName(), current_user.getUserId());
String filename = String.format("%s-%s", audio_file.getOriginalFilename(), soundPath);
// Save audio file to s3 bucket
try {
fileStore.saveAudio(
path,
filename,
Optional.of(metadata),
audio_file.getInputStream()
);
} catch (IOException e) {
throw new IllegalStateException(e);
}
return soundProfile;
}
I would like to send the SoundProfileRequest object and the multipart file separately, meaning I don't want to append the file to a FormData object, but I would still like to send the file along with the form fields in a single post request.
For example in my front-end React Component:
export default function UploadSoundProfile() {
const [caseBrand, setCaseBrand] = useState("");
const [caseModel, setCaseModel] = useState("");
const [switches, setSwitches] = useState("");
const [keycaps, setKeycaps] = useState("");
const [lube, setLube] = useState("");
const [stabilizers, setStabilizers] = useState("");
const [mods, setMods] = useState("");
const [selectedFile, setSelectedFile] = useState("");
const history = useHistory();
const createSoundProfile = (e) => {
e.preventDefault();
const url = "/sound-profile/upload";
const formData = new FormData();
formData.append('caseBrand', caseBrand);
formData.append('caseModel', caseModel);
formData.append('switches', switches);
formData.append('keycaps', keycaps);
formData.append('lube', lube);
formData.append('stabilizers', stabilizers);
formData.append('mods', mods);
**// SHOULD FILE ALSO BE APPENDED TO FORMDATA OBJECT HERE?**
formData.append('audio_file', selectedFile);
const config = {
headers: {
"content-type": "multipart/form-data"
}
}
uploadProfileService.createSoundProfile(url, formData, config);
history.push("/sound-profile/profile");
};
return (
...
)
}
Is there a way to make the POST request with Axios without appending the file to the FormData object while still making a single post request?
I am unsure of how to accomplish this, or if it is possible. I have seen other posts where a file is being .append() to a FormData object, but I am unsure if this will cause an error on the backend.
Thanks for any help in advance!

React Redux Firebase Upload File Object

Trying to pass the file object to redux action and perform the function inside of an redux action, not sure its the correct way? but basically i want back downloadURL from firebase upload complete so I can show image front end.
createLocation(event) {
event.preventDefault();
const fileObject = this.state.file;
const test = {
fileObject
}
this.props.uploadImage_func(test);
}
and action function:
export function uploadImage_func(fileObject) {
return dispatch => {
const fileName = 'myimage';
const storageRef = firebase.storage().ref('test/' + fileName);
const task = storageRef.put(fileObject);
task.on('state_changed',
function complete(snapshot) {
const downloadURL = task.snapshot.downloadURL;
},
).then(function () {
dispatch(attemptLogin({
...downloadURL
}));
});
}
}
error:
As you can see you have got an error Invalid argument in 'put' at index 0: Expected Blob or File. So first of all you need path exactly File or Blob. If you did right in you createLocation and got file object than you need not to wrap it in const test object more. That action causes unnecessary nesting, so just path fileObject as it is. And more. When you subscribe for firebase UploadTask on event you need to path callback functions and do it in a right order, so try to use next:
uploadTask.on('state_changed',
(snapshot) => {
// here you could log loading information in percents but uploading is not finished yes
console.log((snapshot.bytesTransferred / snapshot.totalBytes) * 100);
},
(error) => console.log(error),
() => {
// And after uploading is complete you could get your download url
console.log('Call save img', uploadTask.snapshot.downloadURL);
}
);
For more information read documentation for Firebase Storage (Upload files)

Resources