Firebase文件上传无法使用.on()监听进度问题求助
问题解决:uploadtask.on is not a function
错误根源
你使用的uploadBytes是Firebase Storage的简单上传方法,它返回的是Promise对象,没有.on()方法用于监听上传状态。要实现进度追踪,必须使用支持可恢复上传的uploadBytesResumable方法,该方法返回UploadTask实例,这个实例才具备.on()状态监听能力。
修复步骤
1. 修改导入语句
将uploadBytes替换为uploadBytesResumable:
import {ref, uploadBytesResumable, listAll, getDownloadURL} from "firebase/storage"
2. 更新上传逻辑
把uploadBytes调用改为uploadBytesResumable,保留状态监听逻辑:
const upLoadImage = () =>{ if (imageUpload ==null) return; const imageRef = ref(proStorage, `images/${imageUpload.name + v4()}`) // 替换uploadBytes为uploadBytesResumable const uploadtask = uploadBytesResumable(imageRef, imageUpload) uploadtask.on('state_changed', (snapshot) => { const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100; console.log('Upload is ' + progress + '% done'); switch (snapshot.state) { case 'paused': console.log('Upload is paused'); break; case 'running': console.log('Upload is running'); break; } }, (error) => { console.error('上传失败:', error); }, () => { getDownloadURL(uploadtask.snapshot.ref).then((downloadURL) => { console.log('File available at', downloadURL); alert('Image Uploaded') }); } ); }
3. 调整提示位置
将alert('Image Uploaded')移到上传成功的回调中,避免上传未完成就弹出提示。
完整修正后的Uploadform组件代码
import React, { useEffect, useState } from 'react'; import {proStorage} from '../firebase/config'; import {ref, uploadBytesResumable, listAll, getDownloadURL} from "firebase/storage" import { v4 } from 'uuid'; const Uploadform = () => { const [imageUpload, setImageUpload] = useState(null) const [imageList,setImageList] = useState([]) const [uploadProgress, setUploadProgress] = useState(0) // 新增进度状态 const upLoadImage = () =>{ if (imageUpload ==null) return; const imageRef = ref(proStorage, `images/${imageUpload.name + v4()}`) const uploadtask = uploadBytesResumable(imageRef, imageUpload) uploadtask.on('state_changed', (snapshot) => { const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100; setUploadProgress(Math.round(progress)) console.log('Upload is ' + progress + '% done'); switch (snapshot.state) { case 'paused': console.log('Upload is paused'); break; case 'running': console.log('Upload is running'); break; } }, (error) => { console.error('上传出错:', error); alert('上传失败,请重试') }, () => { getDownloadURL(uploadtask.snapshot.ref).then((downloadURL) => { console.log('File available at', downloadURL); // 上传完成后直接更新图片列表 setImageList(prev => [...prev, downloadURL]) alert('Image Uploaded') setUploadProgress(0) setImageUpload(null) }); } ); } const imageListRef = ref(proStorage, "images/") useEffect(() => { listAll(imageListRef).then((response) => { response.items.forEach((item) => { getDownloadURL(item).then((url) => { setImageList((prev) => [...prev,url]) }) }) }) // eslint-disable-next-line },[]) return ( <div className='absolute h-full w-full flex justify-center items-center'> <div className='h-[50%] w-[50%] justify-center items-center border'> <div className='h-full w-full flex flex-col items-center justify-center gap-4'> <input type='file' onChange={(e) => {setImageUpload(e.target.files[0])}} /> {uploadProgress > 0 && <p>上传进度:{uploadProgress}%</p>} <button className='bg-black text-white' onClick={upLoadImage} disabled={!imageUpload}>Upload Image</button> </div> <div className='flex flex-wrap gap-2 mt-4'> {imageList.map((url, index) => { return <img key={index} src={url} alt='uploaded-img' className='w-24 h-24 object-cover'></img> })} </div> </div> </div> ) } export default Uploadform
额外说明
- Firebase v9+采用模块化API设计,将上传功能拆分为
uploadBytes(简单上传,无进度监听)和uploadBytesResumable(可恢复上传,支持状态监听、暂停/恢复操作) - 如需暂停或恢复上传,可调用
uploadtask.pause()和uploadtask.resume()方法
内容的提问来源于stack exchange,提问作者Brian
相关产品推荐
相关产品推荐

