When I upload a .mp3
audio file or a .jpg
picture to Firebase Cloud Storage I get this error:
TypeError: Cannot read properties of undefined (reading 'byteLength')
What is byteLength
?
I tried uploading a .jpg
with raw uploadString
. The file appeared in Storage but it was only 15B when it should have been 100KB.
The documentation Upload files with Cloud Storage on Web doesn’t say anything about specifying MIME types when uploading files.
Writing to the Storage emulator executes without errors but no files appear.
Here’s the Firebase Cloud Function I’m using.
import { initializeApp } from "firebase/app";
import * as functions from "firebase-functions";
import { getStorage, ref, uploadBytes, uploadString, connectStorageEmulator } from "firebase/storage";
const firebaseConfig = {
apiKey: "...",
authDomain: "my-awesome-app.firebaseapp.com",
databaseURL: "https://my-awesome-app.firebaseio.com",
projectId: "my-awesome-app",
storageBucket: "my-awesome-app.appspot.com",
messagingSenderId: "...",
appId: "..."
};
const app = initializeApp(firebaseConfig);
export const ByteMe = functions.firestore.document('ByteMe/{userID}').onUpdate((change, context) => {
const storage = getStorage();
const storageRef = ref(storage, 'gs://my-awesome-app.appspot.com/Pictures/bootchkas.jpg');
connectStorageEmulator(storage, "localhost", 9199); // comment out to write to the cloud
async function uploadPicture() {
try {
uploadString(storageRef, './bootchkas.jpg').then((snapshot) => {
console.log('Uploaded a raw string!');
});
} catch (error) {
console.error(error);
}
}
return uploadPicture();
});
2
Answers
As @Dharmaraj and @Alexander N. said,
uploadString
just uploads the subsequent string, not a file. The error messagemeans that
undefined
is a missing ES module that you didn't import.The following code almost uploads a file...with one problem.
uploadBytes
uploads files (or blobs). It take three parameters: thestorageRef
or path to a location in Storage;file
, which is the file to be uploaded to Storage; andmetadata
, which includes the MIME type of the file.I've set the MIME
contentType
to'image/jpeg'
.This leaves
file
. We need to import the file as an ES module:But that doesn't work because
bootchkas.jpg
isn't an ES module.We need to use WebPack to make an ES module from
bootchkas.jpg
. The WebPack documentation has a section Loading Images. I followed the tutorial and was able to loadbootchkas.com
into a HTML page. But when I tried to use WebPack with my Firebase Cloud Function it threw error after error.Here's the
webpack.config.js
I ended up with (bizarrely, the tutorial use CommonJS modules):This throws about a half-dozen error, which I fixed one by one.
Then I restarted the Firebase emulator and it couldn't read
functions/package.json
. WebPack requires changing"main": "./src/index.js",
to"private": true,
which makes Firebase unable to reach your Cloud Functions. Trying to get WebPack to work with Firebase Cloud Functions is too difficult.As @Dharmaraj indicated, it looks like you are just uploading the string
./bootchkas.jpg
-> its exactly 15 bytes long. Is this the code you wanted to use to upload the file? If it is, it won’t find the file, but only find the string./bookchkas.jpg
.If you want to upload a file as a string you would either need to encode the file as base64 or load the file itself and send that to firebase storage. If using the browser APIs, you can fetch the file using something akin to this. If using nodejs and a server side application, you will want to refer to the file using the filesystem nodejs package.