Firebase v9批量上传图片到Storage获取URL报ref.put非函数错误
错误原因
Firebase v9 采用模块化函数式API设计,和v8版本的命名空间链式调用API不兼容。原有代码中storage.ref().put()、ref.getDownloadURL()都是v8版本的实例方法调用写法,v9版本中文件引用创建、上传、获取下载地址的能力都是独立导出的工具函数,不存在挂载在ref对象上的put方法,因此抛出ref.put is not a function错误。
v9版本适配实现
前置依赖导入
首先确保从firebase/storage包中导入需要用到的模块化方法,同时引入项目中已经初始化好的storage实例:
import { ref, uploadBytes, getDownloadURL } from "firebase/storage"; // 替换为自身项目中Firebase初始化文件导出的storage实例路径 import { storage } from "@/utils/firebase";
顺序上传实现(和原有代码逻辑完全一致)
按文件列表顺序逐个上传,返回的URL数组顺序和传入的文件列表顺序严格对应:
export const multiImageUpload = async (path = "Products", imageFileList) => { const imagesUrlArray = []; // 提取原始文件对象 const fileArr = imageFileList.map((item) => item.originFileObj); for (const file of fileArr) { // 创建对应存储路径的文件引用 const storageRef = ref(storage, `${path}/${file.name}`); // 执行文件上传 const uploadSnapshot = await uploadBytes(storageRef, file); // 获取上传后文件的访问URL const imageUrl = await getDownloadURL(uploadSnapshot.ref); imagesUrlArray.push(imageUrl); } return imagesUrlArray; };
并行上传优化版本
如果不需要严格的逐个上传逻辑,可以使用Promise.all并行处理所有上传任务,上传速度更快,最终返回的URL数组顺序依然和原文件列表一致:
export const multiImageUpload = async (path = "Products", imageFileList) => { const fileArr = imageFileList.map((item) => item.originFileObj); const uploadTasks = fileArr.map(async (file) => { const storageRef = ref(storage, `${path}/${file.name}`); const uploadSnapshot = await uploadBytes(storageRef, file); return getDownloadURL(uploadSnapshot.ref); }); return Promise.all(uploadTasks); };
补充说明
- 如果需要实现上传进度监听、断点续传能力,可以将
uploadBytes替换为uploadBytesResumable方法,传入对应的进度回调即可 - 不要在项目中混用v8兼容包(
firebase/compat/*路径下的导入)和v9原生模块化API,避免出现实例类型不匹配的异常 - 如果上传时需要携带自定义元数据,可以在
uploadBytes的第三个参数传入包含customMetadata字段的配置对象
内容的提问来源于stack exchange,提问作者Shaheer
相关产品推荐
相关产品推荐

