Reputation: 10930
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();
});
Upvotes: 1
Views: 539
Reputation: 10930
As @Dharmaraj and @Alexander N. said, uploadString
just uploads the subsequent string, not a file. The error message
TypeError: Cannot read properties of undefined (reading '...')
means that undefined
is a missing ES module that you didn't import.
The following code almost uploads a file...with one problem.
import file from "./bootchkas.jpg";
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'); // location to write to
connectStorageEmulator(storage, "localhost", 9199); // comment out to write to the cloud
const metadata = {
contentType: 'image/jpeg',
};
async function uploadPicture() {
try {
await uploadBytes(storageRef, file, metadata);
console.log('Uploaded a file!');
} catch (error) {
console.error(error);
}
}
return uploadPicture();
});
uploadBytes
uploads files (or blobs). It take three parameters: the storageRef
or path to a location in Storage; file
, which is the file to be uploaded to Storage; and metadata
, 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:
import file = './bootchkas.jpg`;
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 load bootchkas.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):
import path from "path"
const __dirname = "/Users/TDK/VisualStudioCodeProjects/CloudFunctions/functions"
const exportMe = {
mode: 'development',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource',
},
],
},
};
export default exportMe;
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.
Upvotes: 0
Reputation: 1592
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.
Upvotes: 1