Reputation: 167
I am building an app using react-native and expo. One feature of the app allows a user to record audio and then upload it to Firebase Storage. I manage to successfully record the audio and also manage to retrieve the cached file as a blob but when trying to upload it to Firebase Storage it fails with error code 400, "Bad Request. Could not create object". What baffles me is that I use the same process to upload images which works perfectly. Why does it fail for audio files?
I manage to record the audio successfully and I retrieve the cached file (as a blob) using XMLHttpRequest. The resultant blob that outputs when I log it to the console looks something like this:
Blob {
"_data": Object {
"blobId": "lengthy blob id",
"name": "recording-XXXXXX.m4a",
"offset": 0,
"size": 371097,
"type": "audio/x-m4a",
},
}
When I try uploading to Firebase Storage using ref.put(blob) it returns with a 400 error: "Bad Request. Could not create object". I have also tried supplying the contentType as part of the metadata to see if that will make a difference but to no avail.
This is how I fetch my file:
const blob = await new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = () => {
resolve(xhr.response);
};
xhr.onerror = (e) => {
reject(new TypeError('Network request failed'));
};
xhr.responseType = 'blob';
xhr.open('GET', uri, true);
xhr.send(null);
});
To upload the blob to Firebase Storage I do the following:
const clientuid = 123;
const siteid = 'ABC';
const audioName = `${Date.now}.m4a`;
this.setState({ uploading: true });
const ref = firebase.storage().ref().child(`audio/${clientuid}/${siteid}/${audioName}`);
ref.put(blob)
.then(async (snapshot) => {
const fullUrl = await snapshot.ref.getDownloadURL();
// Upload the Url to Firebase realtime database...
Alert.alert('Upload Successful');
.catch((error) => {
console.log(error.serverResponse);
Alert.alert('Failed to create object!');
})
.finally(() => {
blob.close()
this.setState({ uploading: false });
});
The upload fails with the following error.serverResponse:
{
"error": {
"code": 400,
"message": "Bad Request. Could not create object",
"status": "CREATE_OBJECT"
}
}
Upvotes: 1
Views: 2386
Reputation: 1
I think you have to check the size of blob
if (blob.size >= 2000000) {
return;
}
This is my work:
const blob = await new Promise<Blob>((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = function () {
resolve(xhr.response);
};
xhr.onerror = function (e) {
reject(new TypeError("Network request failed"));
};
xhr.responseType = "blob";
xhr.open("GET", uri[i], true);
xhr.send(null);
});
if (blob.size >= 2000000) {
return urls;
}
if (auth.currentUser) {
const fileRef = ref(
storage,
auth.currentUser.uid +
"/recordings/" +
diaryId
);
await uploadBytes(fileRef, blob)
.then((snapshot) => {
console.log("Uploaded");
})
.catch((err) => {
console.log(err);
});
const url = await getDownloadURL(fileRef);
console.log(url);
}
Upvotes: 0
Reputation: 71
In your case I think you can also create the blob by fetching the file with the file path.
let res = await fetch(filePath);
let blob = res.blob
In my case this always works.
Upvotes: 1