I want to build editable profile screen that user can upload their image file to profile.
When user upload image, CircleAvatar is changing but application don't save user statement. If I restart application or push another screen, It come back default image. What I confuse thing is firebase storage have image file that user uploaded.
profile_screen.dart
Uint8List? _image;
void selectImage() async {
Uint8List img = await imageSelector(ImageSource.gallery);
setState(() {
_image = img;
});
saveProfile();
}
void saveProfile() async {
String resp = await StoreData().saveData(file: _image!);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: StreamBuilder<DocumentSnapshot>(
stream:
_firestore.collection('Users').doc(currentUser.email).snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
final userData = snapshot.data!.data() as Map<String, dynamic>;
return ListView(
children: [
const SizedBox(
height: 50.0,
),
Stack(
alignment: Alignment.center,
children: [
_image != null
? CircleAvatar(
radius: 80,
backgroundImage: MemoryImage(_image!),
)
: const CircleAvatar(
radius: 80,
backgroundImage: NetworkImage(
'https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_1280.png'),
),
Positioned(
bottom: -10.0,
right: 60.0,
child: IconButton(
onPressed: selectImage,
icon: const Icon(
Icons.edit,
color: Colors.grey,
)),
)
],
),
const SizedBox(
height: 15.0,
),
Text(
currentUser.email!,
textAlign: TextAlign.center,
style: kSmallText.copyWith(color: Colors.grey[800]),
),
const SizedBox(
height: 50.0,
),
MyTextBox(
sectionName: 'username',
text: userData['username'],
onPressed: () => editField('username'),
),
MyTextBox(
sectionName: 'empty bio',
text: userData['bio'],
onPressed: () => editField('bio'),
),
const SizedBox(
height: 15.0,
),
Center(
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.grey[200],
),
onPressed: () {
_auth.signOut();
Navigator.pushNamedAndRemoveUntil(
context, WelcomeScreen.id, (route) => false);
},
child: const Text(
'Logout',
style: TextStyle(
color: mediumComb,
fontSize: 15,
fontWeight: FontWeight.w600),
),
),
),
],
);
} else if (snapshot.hasError) {
return Center(
child: Text('Error${snapshot.error}'),
);
}
return const CircularProgressIndicator();
},
),
);
}
}
add_data.dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'dart:typed_data';
final FirebaseStorage _storage = FirebaseStorage.instance;
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
class StoreData {
Future<String> uploadImageToStorage(String childName, Uint8List file) async {
Reference ref = _storage.ref().child(childName);
UploadTask uploadTask = ref.putData(file);
TaskSnapshot snapshot = await uploadTask;
String downloadUrl = await snapshot.ref.getDownloadURL();
return downloadUrl;
}
Future<String> saveData({
required Uint8List file,
}) async {
String resp = "Some Error Occured";
try {
String imageURL = await uploadImageToStorage('ProfileImage', file);
_firestore.collection('userProfile').add({
'imageLink': imageURL,
});
resp = 'success';
} catch (err) {
resp = err.toString();
}
return resp;
}
}
image_selector.dart
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
imageSelector(ImageSource source) async {
final ImagePicker imagePicker = ImagePicker();
XFile? file = await imagePicker.pickImage(source: source);
if (file != null) {
return await file.readAsBytes();
}
print('No Images Selected');
}
I think it is related user statement setting or something but I don't really know how to figure out.
Image file have successfully uploaded :
enter image description here
pubspec.yaml or ios/info.plist or firebase rule setting was done.
enter image description here
enter image description here
enter image description here
I was following this two video.
https://youtu.be/BjowvNSdWYE?si=31Y4lf67LHgWHHLk
https://youtu.be/5kjjkIdwwN8?si=y45OWVVnNf8yeDPN
Thanks for reading this question