Firebase存储'上载字节':“类型错误:无法读取未定义的属性(阅读'byteLength')”

siotufzp  于 2022-11-17  发布在  其他
关注(0)|答案(1)|浏览(189)

我正在尝试编写一个Firebase Cloud函数,该函数使用uploadBytes将文件上传到Firebase Cloud Storage。我正在执行documentation for web apps。无论我做什么都会抛出此错误:

TypeError: Cannot read properties of undefined (reading 'byteLength')

这个错误信息没有在documentation page for error handling上列出,但我推断这个错误信息意味着它找不到要上传的文件。我在模拟器和云上都收到了这个错误。
让我们从uploadString开始,它是有效的。

import { initializeApp } from "firebase/app";
import * as functions from "firebase-functions";
import { getStorage, ref, uploadBytes, uploadString, connectStorageEmulator } from "firebase/storage";
const firebaseConfig = {
    apiKey: "12345",
    authDomain: "my-awesome-app.firebaseapp.com",
    databaseURL: "https://my-awesome-app.firebaseio.com",
    projectId: "my-awesome-app",
    storageBucket: "my-awesome-app.appspot.com",
    messagingSenderId: "12345",
    appId: "12345"
};
initializeApp(firebaseConfig);

export const StringMe = functions.firestore.document('StringMe/{userID}').onUpdate((change, context) => {
    const storage = getStorage();
    // const storageRef = ref(storage, 'message.txt'); // location to write to
    // connectStorageEmulator(storage, "localhost", 9199); // comment out to write to the cloud
    const storageRef = ref(storage, 'gs://my-awesome-app.appspot.com/Pictures/message.txt');
    const message = "Hello world!";

    async function uploadMessage() {
        try {
            await uploadString(storageRef, message);
            console.log("Uploaded a string!");
        } catch (error) {
            console.error(error);
        }
    };

    return uploadMessage()
});

这会上传一个字符串到我的Cloud Firestore,然后记录Uploaded a string!Finished "StringMe" in 417.150521ms。60秒后,它会抛出一个错误:

functions: Your function timed out after ~60s. To configure this timeout, see
      https://firebase.google.com/docs/functions/manage-functions#set_timeout_and_memory_allocation.
⚠  Your function was killed because it raised an unhandled error.

该错误似乎是Firebase CLI中的一个错误,我忽略了它。
让我们在模拟器中尝试一下,我们将注解掉storageRef,并取消注解两行。

const storageRef = ref(storage, 'message.txt');
connectStorageEmulator(storage, "localhost", 9199);

这不会引发任何错误(60秒超时除外),不会记录任何内容,也不会将任何内容写入存储。为什么存储仿真器无法工作?
现在让我们制作一个要上传的文件。

// my-module.js

export const file = "Hello world";

然后我们将其上传到云存储。

import { initializeApp } from "firebase/app";
import * as functions from "firebase-functions";
import { getStorage, ref, uploadBytes, uploadString, connectStorageEmulator } from "firebase/storage";
import { file } from "./my-module.js";
const firebaseConfig = {
    apiKey: "...",
    authDomain: "...",
    databaseURL: "...",
    projectId: "...",
    storageBucket: "...",
    messagingSenderId: "...",
    appId: "..."
};
initializeApp(firebaseConfig);

export const ByteMe = functions.firestore.document('ByteMe/{userID}').onUpdate((change, context) => {
    const storage = getStorage(app);
    // const storageRef = ref(storage, 'hello.txt'); // location to write to
    // connectStorageEmulator(storage, "localhost", 9199); // comment out to write to the cloud
    const storageRef = ref(storage, 'gs://my-awesome-app.appspot.com/Pictures/hello.txt');

    const metadata = {
        contentType: 'text/plain',
    };

    async function uploadFile() {
        try {
            console.log(file);
            await uploadBytes(storageRef, file, metadata);
            console.log('Uploaded a file!');
        } catch (error) {
            console.error(error);
        }
    }

    return uploadFile();
});

这将记录Hello world(我们知道该文件在函数中可用且可读),然后抛出以下错误:

TypeError: Cannot read properties of undefined (reading 'byteLength')

有些东西是undefined。除了字符串变成了file之外,代码中没有任何变化。错误消息一定是说它无法读取文件。byteLength似乎是一个红色的鲱鱼,最好忽略,除非你喜欢兔子洞。为什么uploadBytes无法读取文件?
切换到仿真器会掷回相同的错误消息。
让我们尝试从API获取一个文件,然后将其上传到存储。

import { initializeApp } from "firebase/app";
import * as functions from "firebase-functions";
import { getStorage, ref, uploadBytes, uploadString, connectStorageEmulator } from "firebase/storage";
import got from 'got';

const firebaseConfig = {
    apiKey: "...",
    authDomain: "...",
    databaseURL: "...",
    projectId: "...",
    storageBucket: "...",
    messagingSenderId: "...",
    appId: "..."
};
initializeApp(firebaseConfig);

export const ByteAPI = functions.firestore.document('ByteAPI/{userID}').onUpdate((change, context) => {
    const storage = getStorage();
    // const storageRef = ref(storage, 'picture.jpg'); // location to write to
    // connectStorageEmulator(storage, "localhost", 9199); // comment out to write to the cloud
    const storageRef = ref(storage, 'gs://my-awesome-app.appspot.com/Pictures/winter.mp3');

    const metadata = {
        contentType: 'audio/mpeg',
    };

    async function uploadFile() {
        try {
            let file = await got('https://audio.oxforddictionaries.com/en/mp3/winter__us_2.mp3');
            await uploadBytes(storageRef, file, metadata);
            console.log('Uploaded a file!');
        } catch (error) {
            console.error(error);
        }
    }

    return uploadFile();
});

您可以单击https://audio.oxforddictionaries.com/en/mp3/winter__us_2.mp3并收听音频文件。
对于云存储或模拟器,这会引发相同的错误:

TypeError: Cannot read properties of undefined (reading 'byteLength')

我也试着上传一个Uint8Array,同样的错误信息。uploadBytes坏了吗?

r7knjye2

r7knjye21#

我能够从牛津英语词典API下载音频文件,并通过将file更改为file['rawBody']将其上传到云存储:

await uploadBytes(storageRef, file['rawBody'], metadata);

这对上传Hello world文本文件不起作用。文档说uploadBytes将处理“JavaScript文件和Blob API”。这与JSON文件和缓冲区有关,我不明白。我将继续研究这一点。

相关问题