PDF转Blob上传至Firebase Storage后无法打开问题求助
问题分析与修复方案
尝试将PDF转换为Blob上传至Firebase Storage,控制台可见已上传的PDF文件,但无法打开,报错:"Failed to load PDF file"。
现有代码
转换函数
const uriToBlob = async (uri) => { try { const response = await fetch(uri); if (!response.ok) { throw new Error('Failed to fetch resource'); } const blob = await response.blob(); return blob; } catch (error) { throw error; } };
上传函数
export const uploadFile = async (fileUri, filename, course, isPublic) => { const userCredentials = getCredentials(); if (!userCredentials) { console.error('User credentials not found'); return; } try { const fileBlob = await uriToBlob(fileUri); console.log('Blob size:', fileBlob.size); const storage = getStorage(); const storageRef = ref(storage, 'notes/' + filename); const metadata = { contentType: 'application/pdf' }; const snapshot = await uploadBytes(storageRef, fileBlob, metadata); const fileUrl = await getDownloadURL(storageRef); console.log('File URL:', fileUrl); } catch (error) { console.error('Error uploading file:', error); } // Get current user ID const userId = auth.currentUser.uid; // Add file metadata to Firestore const notesCollectionRef = collection(firestoreInstance, 'notes/'); await addDoc(notesCollectionRef, { filename: filename, university: userCredentials?.university || '', // Ensure university field is not undefined department: userCredentials?.department || '', course: course, contentType: 'application/pdf', isPublic: isPublic, userId: userId, url: fileUrl, // Store download URL in Firestore }); console.log('File uploaded successfully'); };
调用方式
uploadFile('Result.pdf','result','Algs',true);
排查与修复步骤
1. 确认文件URI有效性
调用时传入的'Result.pdf'仅为文件名,需根据运行环境调整:
- Web环境:需传入File对象,或确保文件在项目可访问路径下(如
./public/Result.pdf); - 移动端:需传入完整文件URI(如
file:///storage/emulated/0/Documents/Result.pdf),不能只用文件名。
2. 验证Blob内容完整性
转换后打印Blob的类型和大小,确认是否为有效PDF:
const fileBlob = await uriToBlob(fileUri); console.log('Blob type:', fileBlob.type); // 正常应输出application/pdf console.log('Blob size:', fileBlob.size); // 需与原PDF文件大小一致
若Web环境直接处理File对象,可简化转换逻辑:
const fileToBlob = (file) => new Blob([file], { type: 'application/pdf' });
3. 修复变量作用域问题
当前fileUrl定义在try块内部,若上传出错会导致Firestore存储无效URL。将Firestore操作移至try块内:
export const uploadFile = async (fileUri, filename, course, isPublic) => { const userCredentials = getCredentials(); if (!userCredentials) { console.error('User credentials not found'); return; } try { const fileBlob = await uriToBlob(fileUri); console.log('Blob size:', fileBlob.size); const storage = getStorage(); const storageRef = ref(storage, 'notes/' + filename); const metadata = { contentType: 'application/pdf' }; const snapshot = await uploadBytes(storageRef, fileBlob, metadata); const fileUrl = await getDownloadURL(storageRef); console.log('File URL:', fileUrl); // 上传成功后再写入Firestore const userId = auth.currentUser.uid; const notesCollectionRef = collection(firestoreInstance, 'notes/'); await addDoc(notesCollectionRef, { filename: filename, university: userCredentials?.university || '', department: userCredentials?.department || '', course: course, contentType: 'application/pdf', isPublic: isPublic, userId: userId, url: fileUrl, }); console.log('File uploaded successfully'); } catch (error) { console.error('Error uploading file:', error); } };
4. 让Firebase自动识别文件类型
移除手动指定的contentType,避免类型不匹配:
const metadata = { contentType: null // 交由Firebase自动检测文件类型 };
内容的提问来源于stack exchange,提问作者tasosger
相关产品推荐
相关产品推荐

