我面临的主要问题与使用 Firebase Storage 在 Flutter 应用程序中显示个人资料图像有关。
重新加载后图片不显示:上传图片后,重新加载或再次登录后,个人资料页面不显示上传的图片。该问题与从 Firebase 存储检索下载 URL 并将其与 Firestore 中的用户个人资料数据相关联有关。我也看不到上传到 firestore 的照片链接。
为了解决这些问题,代码已更新以正确检索和显示个人资料图像。下载 URL 是从 Firebase 存储中获取并存储在 Firestore 中,因此可以稍后访问以显示图像。
最终代码应允许用户上传其个人资料图像,在个人资料页面上查看它们,并通过 Firestore 中存储的下载 URL 从 Firebase 存储中获取上传的图像,从而跨会话保留上传的图像。
提前谢谢您!}
class ProfilePage extends StatefulWidget {
@override
_ProfilePageState createState() => _ProfilePageState();
}
class _ProfilePageState extends State<ProfilePage> {
Uint8List? _imageData;
void _selectImage() async {
final pickedFile = await FilePicker.platform.pickFiles(type: FileType.image);
if (pickedFile != null) {
setState(() {
_imageData = pickedFile.files.first.bytes;
});
await _uploadImageToFirebase();
}
}
// Function to check if the file has an allowed extension (png, jpg, jpeg)
bool _isAllowedImage(Uint8List data) {
final mimeType = lookupMimeType('file.jpg', headerBytes: data);
if (mimeType != null &&
(mimeType.startsWith('image/jpeg') ||
mimeType.startsWith('image/png'))) {
return true;
}
return false;
}
// Display the image in the CircleAvatar if it's allowed
Widget _buildProfileImage() {
if (_imageData != null && _isAllowedImage(_imageData!)) {
return CircleAvatar(
radius: 50,
backgroundImage: MemoryImage(_imageData!),
);
} else {
// If the image is not available locally, load it from Firebase Storage
return StreamBuilder<DocumentSnapshot>(
stream: _firestore.collection('admin_users').doc(_uid).snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData || !snapshot.data!.exists) {
return CircleAvatar(
radius: 50,
backgroundImage: AssetImage('assets/profile_picture_placeholder.png'),
);
}
Map<String, dynamic>? userData = snapshot.data?.data() as Map<String, dynamic>?;
String? downloadURL = userData?['profile_image_url'];
if (downloadURL != null && downloadURL.isNotEmpty) {
return CircleAvatar(
radius: 50,
backgroundImage: NetworkImage(downloadURL),
);
} else {
return CircleAvatar(
radius: 50,
backgroundImage: AssetImage('assets/profile_picture_placeholder.png'),
);
}
},
);
}
}
final FirebaseAuth _auth = FirebaseAuth.instance;
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
final TextEditingController _firstNameController = TextEditingController();
final TextEditingController _lastNameController = TextEditingController();
final TextEditingController _regionController = TextEditingController();
final TextEditingController _phoneNumberController = TextEditingController();
String? _uid;
bool _isLoading = false;
@override
void initState() {
super.initState();
_getCurrentUser();
}
Future<void> _getCurrentUser() async {
final user = _auth.currentUser;
if (user != null) {
setState(() {
_uid = user.uid;
});
await _getUserData();
}
}
Future<void> _getUserData() async {
if (_uid != null) {
final userData = await _firestore.collection('admin_users').doc(_uid).get();
if (userData.exists) {
setState(() {
_firstNameController.text = userData.get('first_name') ?? '';
_lastNameController.text = userData.get('last_name') ?? '';
_regionController.text = userData.get('region') ?? '';
_phoneNumberController.text = userData.get('phone_number') ?? '';
});
}
}
}
Future<void> _uploadImageToFirebase() async {
if (_imageData != null) {
try {
String uid = _auth.currentUser?.uid ?? '';
String fileName = 'profile_images/$uid.jpg';
// Upload the image to Firebase Storage
await firebase_storage.FirebaseStorage.instance.ref(fileName).putData(_imageData!);
// Get the download URL of the uploaded image
String downloadURL =
await firebase_storage.FirebaseStorage.instance.ref(fileName).getDownloadURL();
// Save the download URL in Firestore
if (_uid != null) {
final userData = {
'profile_image_url': downloadURL,
'first_name': _firstNameController.text.trim(),
'last_name': _lastNameController.text.trim(),
'region': _regionController.text.trim(),
'phone_number': _phoneNumberController.text.trim(),
};
await _firestore.collection('admin_users').doc(_uid).update(userData);
}
} catch (e) {
print('Error uploading image: $e');
}
}
}
Future<void> _updateUserData() async {
if (_uid != null) {
final userData = {
'first_name': _firstNameController.text.trim(),
'last_name': _lastNameController.text.trim(),
'region': _regionController.text.trim(),
'phone_number': _phoneNumberController.text.trim(),
};
await _firestore.collection('admin_users').doc(_uid).set(userData);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Profile Page'),
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => AdminPage()),
);
},
),
),
body: _isLoading
? Center(
child: CircularProgressIndicator(),
)
: SingleChildScrollView(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Stack(
alignment: Alignment.center,
children: [
_buildProfileImage(),
Positioned(
child: IconButton(
onPressed: _selectImage,
icon: Icon(Icons.add_a_photo),
color: Colors.white,
),
),
],
),
SizedBox(height: 16),
Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: TextField(
controller: _firstNameController,
decoration: InputDecoration(labelText: 'First Name'),
),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: TextField(
controller: _lastNameController,
decoration: InputDecoration(labelText: 'Last Name'),
),
),
),
],
),
SizedBox(height: 16),
Padding(
padding: const EdgeInsets.all(16.0),
child: TextField(
controller: _regionController,
decoration: InputDecoration(labelText: 'Region'),
),
),
SizedBox(height: 16),
Padding(
padding: const EdgeInsets.all(16.0),
child: TextField(
controller: _phoneNumberController,
decoration: InputDecoration(labelText: 'Phone Number'),
),
),
SizedBox(height: 16, width: 30),
ElevatedButton(
onPressed: () async {
setState(() {
_isLoading = true;
});
await _updateUserData();
setState(() {
_isLoading = false;
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Profile updated successfully')),
);
},
child: Text('Save'),
),
],
),
),
);
}
}