React中从Firebase Storage下载文件并转换为STL文件的方法
问题描述
尝试从Firebase Storage下载已存储的文件,转换为STL文件供ThreeJs使用,但生成的文件大小始终为0。
现有代码
const [blobData, setBlobData] = useState([]); const storageRef = storageReference( storage, '/storage/testModel.stl', ) if (blobData.length < 1) { getBlob(storageRef).then((data) => {setBlobData(data)}); var testFile = new File([blobData], "testFile.stl"); } console.log("Outside Loop",testFile);
日志情况
日志显示生成的testFile文件大小为0,内部Blob数据为空。
问题原因与修复方案
核心问题
getBlob是异步操作,你在调用它后立刻创建testFile时,blobData仍为初始的空数组,导致生成的文件没有内容。
修复后的代码
import { useState, useEffect } from 'react'; const YourComponent = () => { const [blobData, setBlobData] = useState(null); const storageRef = storageReference(storage, '/storage/testModel.stl'); useEffect(() => { // 避免重复发起请求 if (!blobData) { getBlob(storageRef) .then((data) => { setBlobData(data); // 确保拿到Blob数据后再生成文件 const testFile = new File([data], "testFile.stl", { type: 'application/sla' }); console.log("生成的STL文件", testFile); // 此处可直接将testFile传入ThreeJS处理 }) .catch((error) => { console.error("下载文件失败:", error); }); } }, [blobData, storageRef]); return ( // 你的组件内容 ); };
关键修改点
- 将
useState初始值改为null(getBlob返回Blob对象,而非数组) - 用
useEffect包裹异步请求,防止组件重渲染时重复发起请求 - 将创建
File的逻辑移到getBlob的then回调内,保证使用真实的Blob数据 - 添加错误捕获,便于排查下载失败问题
更优实现(直接对接ThreeJS)
如果不需要将Blob存入组件状态,可直接在下载完成后传入ThreeJS加载器,减少状态更新开销:
import { useEffect } from 'react'; import * as THREE from 'three'; import { STLLoader } from 'three/addons/loaders/STLLoader.js'; const YourComponent = () => { const storageRef = storageReference(storage, '/storage/testModel.stl'); useEffect(() => { getBlob(storageRef) .then((blob) => { const stlUrl = URL.createObjectURL(blob); const loader = new STLLoader(); loader.load(stlUrl, (geometry) => { // 处理加载完成的几何体 const material = new THREE.MeshStandardMaterial({ color: 0xffffff }); const mesh = new THREE.Mesh(geometry, material); // 假设你已创建好scene对象 scene.add(mesh); // 释放URL对象,避免内存泄漏 URL.revokeObjectURL(stlUrl); }); }) .catch((error) => { console.error("加载STL文件失败:", error); }); }, [storageRef]); return ( // 你的组件内容 ); };
内容的提问来源于stack exchange,提问作者Mercyfon
相关产品推荐
相关产品推荐

