【问题标题】:How to pass an array to Firestore?如何将数组传递给 Firestore?
【发布时间】:2021-06-15 10:37:25
【问题描述】:

我正在尝试使用以下代码将数组传递给 Firestore。问题是 Firestore 中的数组始终为空。如果我手动传递一个数组,它就可以工作。如果我 console.log 它输出的数组,它不是空的。

const handleSubmit = (e) => {
    ...
    finally {
        ...
        console.log(photoUrlArray) // THIS OUTPUTS THE ARRAY

        collectionRef.add({
            field1: someData,  THIS GETS POSTED
            photos: photoUrlArray,    THIS DOESN'T
        })
    }
}

如果手动发布一个数组,它可以工作。

collectionRef.add({
    field1: someData,  
    photos: ["url1,jpg","url2.png", "url3.wepb"]  THIS WORKS
})

我意识到我很可能错过了一些非常明显的东西。谁能看看是什么错误?

console.log(photoArray) 的输出是:

[]
0: "https://firebasestorage.googleapis.com/v0/i/t2-dev-9.appspot.com/o/photo2.jpeg?alt=media&token=82e3bd7d-a77a-4045-af71-1a7851bddd7c"
1: "https://firebasestorage.googleapis.com/v0/i/t2-dev-9.appspot.com/o/photo.jpeg?alt=media&token=c71f2fbe-ca64-4189-9403-4d24f1433d77"

长度:2

编辑:这是整个组件的基本版本。 该组件从输入中选择多个图像,循环浏览它们并将它们上传到 Firebase 存储,并将存储 URL 推送到“photoArray”数组”。如何将 photoArray 或其内容发布到 Firestore?

export default function AddPost() {
    
    const fileInput = useRef();
    const photoArray = [];

    function handleSubmit(e) {
        e.preventDefault()
        
        let fileArray = fileInput.current.files;
        for (let i = 0; i < fileArray.length; i++) {
            handleUpload(fileArray[i]);
        }

        console.log(photoArray); // OUTPUTS THE ARRAY
        const collectionRef = useFireStore.collection('posts');
        collectionRef.add({
            field1: someData,   // WORKS
            field2: someMoreData,    // WORKS
            photos: photoArray,    // DOESN'T
        })
    }

    function handleUpload() {
        
        const storageRef = useStorage.ref()
        const fileRef = storageRef.child(file.name)

        fileRef.put(file).then(() => {
            fileRef.getDownloadURL().then(function (url) {
                photoArray.push(url)
            });
       })

    }

    return (
        <form onSubmit={handleSubmit}>
            <input type="file" ref={fileInput}/>
        </form>
    )

}

干杯,马特

【问题讨论】:

  • 您能添加var photoUrlArray 的范围吗?在什么时候实例化这个变量?添加到函数作用域后是否会被修改?
  • 您好,photoUrlArray 变量在容器函数中被实例化,然后被容器内的 handleUpload 和 handleSubmit 函数访问。我在上面代码的“finally{}”部分中放置了一个 console.log 的原因是为了在执行“collectionRef.add”之前检查 photoUrlArray 变量是否确实包含正确的数据,并且确实如此。
  • 如果您提供的complete minimal code sample 不能按您预期的方式工作,这将有所帮助。任何人都应该能够运行该代码来重现您观察到的结果(同时显示这些结果以便我们确认)。如果不准确显示您正在做什么来构建数组,任何我们看不到的错误都可能出现。
  • 当您使用控制台记录该数组时,它不会被填充。它稍后会填充,并且控制台会显示最新值。您可以通过对数组执行 JSON.stringify 之类的操作并记录该字符串来验证这一点。
  • 功能性反应组件听起来像:函数。您在函数体中定义一个常量。这将在每次执行函数时重新声明(重新渲染)。要使 photoArray 的值在渲染中保持不变,您需要告诉 react 它是状态的一部分。为此使用 useState Hook

标签: javascript firebase google-cloud-firestore


【解决方案1】:

这是一些(未经测试的)代码。

看看handleUpload 现在是如何返回一个承诺的,这样你就可以等待它完成后再继续。

export default function AddPost() {

    const fileInput = useRef();
    const photoArray = [];

    function handleSubmit(e) {
        e.preventDefault();

        let fileArray = fileInput.current.files;
        const uploadTasks = [];
        for (let i = 0; i < fileArray.length; i++) {
            uploadTasks.push(handleUpload(fileArray[i]));
        }
        Promise.all(uploadTasks).then(() => {
            console.log(photoArray); // OUTPUTS THE ARRAY
            const collectionRef = useFireStore.collection('posts');
            collectionRef.add({
                field1: someData,   // WORKS
                field2: someMoreData,    // WORKS
                photos: photoArray,    // SHOULD WORK NOW!
            });
        });
    }

    function handleUpload() {

        const storageRef = useStorage.ref();
        const fileRef = storageRef.child(file.name);

        return fileRef.put(file).then(() => {
            return fileRef.getDownloadURL().then(function (url) {
                photoArray.push(url);
            });
        });

    }

    return (
        <form onSubmit={handleSubmit}>
            <input type="file" ref={fileInput} />
        </form>
    );

}

照片的顺序很可能是错误的,因为它们都是并行上传的,并且它们的 URL 是在各自的上传完成时添加的。如果你需要,我会让你找到解决问题的方法。

我还建议您尽可能使用async / await 而不是then()

【讨论】:

  • 你好 Stratubas。效果很好,非常感谢!我将重构以使用异步和等待。照片的顺序目前不是问题 - 一次一个问题!再次感谢 - 马特
【解决方案2】:

我假设你的照片 URL 很长,所以 Firesore 有一些限制, 您能否检查您的 Firebase 日志,看看您是否收到限制错误?

类似的东西 INVALID_ARGUMENT:属性“xxxx”的值超过 1048487 字节。,null))

【讨论】:

  • 您好,Armen,感谢您的回复。请参阅上面的 cmets - 即使它是 console.logs,该数组实际上也是空的。这就是为什么没有任何东西被发送到 Firestore。试图找出数组为空的原因
猜你喜欢
  • 2019-04-14
  • 2023-03-24
  • 2014-03-18
  • 1970-01-01
  • 1970-01-01
  • 2016-04-09
  • 1970-01-01
相关资源
最近更新 更多