Firebase存储上传头像报[object-not-found]错误求助
Firebase Storage 头像上传报错排查:[firebase_storage/object-not-found]
问题说明
开发注册用户头像上传功能,计划将头像存储至Firebase,但在ProfilePage页面出现如下报错:
Error uploading profile picture: [firebase_storage/object-not-found] No object exists at the desired reference
已确认直接操作Firebase集合功能正常,尝试过其他帖子提供的解决方法但未解决问题,相关Flutter代码如下:
imported files here class ProfilePage extends StatefulWidget { @override _ProfilePageState createState() => _ProfilePageState(); } class _ProfilePageState extends State<ProfilePage> { final User? user = FirebaseAuth.instance.currentUser; final FirebaseFirestore _firestore = FirebaseFirestore.instance; File? _imageFile; String? _profileImageUrl; @override void initState() { super.initState(); _loadProfileImage(); } Future<void> _loadProfileImage() async { if (user != null) { DocumentSnapshot userDoc = await _firestore.collection('users').doc(user!.uid).get(); if (userDoc.exists && userDoc.data() != null) { setState(() { _profileImageUrl = userDoc['profilePic']; }); } } } Future<void> _pickImage() async { final pickedFile = await ImagePicker().getImage(source: ImageSource.gallery); if (pickedFile != null) { setState(() { _imageFile = File(pickedFile.path); }); _uploadImage(_imageFile!); } } Future<void> _uploadImage(File imageFile) async { try { String fileName = path.basename(imageFile.path); Reference storageRef = FirebaseStorage.instance.ref().child('profile_pics/$fileName'); final UploadTask uploadTask = storageRef.putFile(imageFile); final TaskSnapshot snapshot = await uploadTask.whenComplete(() => {}); final String downloadUrl = await snapshot.ref.getDownloadURL(); SharedPreferences prefs = await SharedPreferences.getInstance(); String? userId = prefs.getString('userId'); if (userId != null) { await FirebaseFirestore.instance.collection('users').doc(userId).update({ 'profilePic': downloadUrl, }); setState(() { _profileImageUrl = downloadUrl; }); print('Profile picture uploaded successfully: $downloadUrl'); } else { print('User ID not found in SharedPreferences'); } } catch (e) { print('Error uploading profile picture: $e'); } } Future<void> _signOut(BuildContext context) async { await FirebaseAuth.instance.signOut(); SharedPreferences prefs = await SharedPreferences.getInstance(); await prefs.remove('staySignedIn'); await prefs.remove('email'); await prefs.remove('password'); Navigator.pushAndRemoveUntil( context, MaterialPageRoute(builder: (context) => LoginPage()), (Route<dynamic> route) => false, ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(user?.displayName ?? 'Profile'), actions: [ IconButton( icon: Icon(Icons.logout), onPressed: () => _signOut(context), ), ], ), body: SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ GestureDetector( onTap: _pickImage, child: CircleAvatar( radius: 50, backgroundImage: _imageFile != null ? FileImage(_imageFile!) : _profileImageUrl != null ? NetworkImage(_profileImageUrl!) as ImageProvider : null, child: _imageFile == null && _profileImageUrl == null ? Icon(Icons.add_a_photo, size: 50) : null, ), ), SizedBox(height: 20), Text( user?.displayName ?? 'No Name', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), ), ], ), ), ), ); } }
排查与解决方法
1. 检查Firebase Storage权限与路径
- 确认Firebase Storage规则允许当前认证用户写入
profile_pics目录,修改规则为:rules_version = '2'; service firebase.storage { match /b/{bucket}/o { match /profile_pics/{allPaths=**} { allow read, write: if request.auth != null; } } } - 避免重复文件名导致的覆盖或路径问题,建议用用户UID作为唯一文件名:
// 在_uploadImage中替换fileName逻辑 String fileName = '${user!.uid}.jpg';
2. 修复UploadTask完成后的引用逻辑
原代码中whenComplete的写法可能导致快照状态未正确确认,修改为直接等待任务完成并校验状态:
final TaskSnapshot snapshot = await uploadTask; if (snapshot.state == TaskState.success) { final String downloadUrl = await snapshot.ref.getDownloadURL(); // 后续更新Firestore的逻辑 } else { print('上传失败,状态:${snapshot.state}'); }
3. 统一用户ID来源
代码中加载头像用的是FirebaseAuth.instance.currentUser!.uid,但上传时用的是SharedPreferences中的userId,两者可能不一致。统一使用当前认证用户的UID:
// 在_uploadImage中替换userId相关逻辑 if (user != null) { await FirebaseFirestore.instance.collection('users').doc(user!.uid).update({ 'profilePic': downloadUrl, }); setState(() { _profileImageUrl = downloadUrl; }); print('Profile picture uploaded successfully: $downloadUrl'); } else { print('用户未登录'); }
4. 适配ImagePicker最新版本
如果使用的是最新版image_picker(>=0.8.0),getImage已被弃用,改用pickImage并直接获取文件名:
Future<void> _pickImage() async { final XFile? pickedFile = await ImagePicker().pickImage(source: ImageSource.gallery); if (pickedFile != null) { setState(() { _imageFile = File(pickedFile.path); }); // 直接用XFile的name属性作为文件名 _uploadImage(_imageFile!, pickedFile.name); } } // 调整_uploadImage方法参数 Future<void> _uploadImage(File imageFile, String fileName) async { try { Reference storageRef = FirebaseStorage.instance.ref().child('profile_pics/$fileName'); // ... 剩余逻辑 } catch (e) { print('Error uploading profile picture: $e'); } }
内容的提问来源于stack exchange,提问作者CyberpsychO_O
相关产品推荐
相关产品推荐

