I still new in learning flutter. Currently, I am trying to create the profile page but I encountered some issues with saving the selected image that chosen from the image picker. How can I save the changes of profile image permanently after I choose the image from the gallery because when I move other page and back to the profile page, the picture that changed will back to the default Image.asset('img/profile2.png',fit: BoxFit.cover). Another issue is how can I store the profile image into Firebase Firestore and track back the profile image if exist? Please help me guys, appreciate those help, thank you.
Code:
// ignore_for_file: avoid_print, unused_local_variable
import 'dart:io';
import 'dart:typed_data';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:fyp_version1/models/empty_content_animation_view.dart';
import 'package:fyp_version1/models/image_store.dart';
import 'package:fyp_version1/utils.dart';
import 'package:fyp_version1/widgets/profile_text_box.dart';
import 'package:get/get.dart';
import 'package:image_picker/image_picker.dart';
class ProfilePage extends StatefulWidget {
const ProfilePage({super.key});
@override
State<ProfilePage> createState() => _ProfilePageState();
}
class _ProfilePageState extends State<ProfilePage> {
// current user
final currentUser = FirebaseAuth.instance.currentUser!;
pickImage(ImageSource source) async {
// pick image from device gallery
final ImagePicker _imagePicker = ImagePicker();
XFile? _file = await _imagePicker.pickImage(source: source);
if (_file != null) {
return await _file.readAsBytes();
}
print('No Images Selected');
}
// edit field
Future<void> editField(String field) async {
String newName = '';
await showDialog(
context: context,
builder: (context) => AlertDialog(
backgroundColor: Colors.grey[900],
title: Text(
'Edit $field',
style: const TextStyle(
color: Colors.white,
),
),
content: TextField(
autofocus: true,
style: const TextStyle(color: Colors.white),
decoration: InputDecoration(
hintText: 'Enter new $field',
hintStyle: const TextStyle(color: Colors.grey),
),
onChanged: (value) {
newName = value;
},
),
actions: [
// cancel button
TextButton(
child: const Text(
'Cancel',
style: TextStyle(color: Colors.white),
),
onPressed: () => Navigator.pop(context),
),
// save button
TextButton(
child: const Text(
'Save',
style: TextStyle(color: Colors.white),
),
onPressed: () => Navigator.of(context).pop(newName),
),
],
),
);
// update profile details in Firebase Firestore
if (newName.trim().isNotEmpty) {
// only update if there is something in the textfield
await FirebaseFirestore.instance
.collection('Users')
.doc(currentUser.email)
.update({field: newName});
}
}
// change image
Uint8List? _image;
void selectImage() async {
Uint8List img = await pickImage(ImageSource.gallery);
setState(() {
_image = img;
});
}
File? image;
Future takeImage(ImageSource source) async {
final image = await ImagePicker().pickImage(source: ImageSource.gallery);
final imageTemp = File(image!.path);
setState(() {
this.image = imageTemp;
});
}
Future<void> saveImage() async {
String file;
String resp = await StoreData().saveData(file: _image!);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text('Profile Page'),
backgroundColor: const Color.fromARGB(153, 121, 133, 248),
),
body: StreamBuilder<DocumentSnapshot>(
stream: FirebaseFirestore.instance
.collection('Users')
.doc(currentUser.email)
.snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
final userData = snapshot.data!.data() as Map<String, dynamic>;
return ListView(
children: [
// imageProfile(),
const SizedBox(height: 50),
_image != null
? CircleAvatar(
radius: 60,
backgroundImage: MemoryImage(_image!),
)
: CircleAvatar(
radius: 60,
backgroundColor: Colors.black,
child: ClipOval(
child: Image.asset(
'img/profile2.png',
fit: BoxFit.cover,
),
),
),
IconButton(
alignment: const Alignment(0.2, -5),
color: Colors.green,
hoverColor: Colors.grey,
tooltip: 'Edit',
onPressed: () {
selectImage();
print('Edit Image');
},
icon: const Icon(Icons.add_a_photo_rounded),
),
const SizedBox(height: 10),
Text(
currentUser.email!,
textAlign: TextAlign.center,
style: const TextStyle(color: Colors.black),
),
const SizedBox(height: 50),
// user details
const Padding(
padding: EdgeInsets.only(left: 25.0),
child: Text(
'My Details',
style: TextStyle(color: Colors.black),
),
),
// username
ProfileTextBox(
text: userData['username'],
sectionName: 'username',
onPressed: () => editField('username'),
),
const SizedBox(height: 50),
TextButton.icon(
onPressed: saveImage,
icon: const Icon(Icons.save),
label: const Text('Save'),
)
],
);
} else if (snapshot.hasError) {
Get.snackbar(
'Error',
'Error${snapshot.error}',
backgroundColor: Colors.white,
snackPosition: SnackPosition.BOTTOM,
colorText: Colors.black,
icon: const Icon(
Icons.warning_amber_rounded,
color: Colors.red,
),
);
}
return const EmptyContentsAnimationView();
},
));
}
}
Image: