Flutter Firebase - 在 Firestore 上更改图像时更新用户个人资料图像 returns 出错
Flutter Firebase - updating user profile image returns an error while the image change on Firestore
我有一个带有个人资料页面的应用程序,我想在其中有一张个人资料图片,用户可以随时更新。
我现在拥有的代码执行以下操作:StreamBuilder 将获取包含当前用户 UID 的 Firestore 集合,并构建一个 Image.network 获取文档“URL”来自 snapshot.data.
问题:
第一次,当用户创建新用户时,我在图像上有一个占位符,当用户从图库中选择新图像时,它会 return 更新之间的时间错误收集并更新 UI,然后更改为新图像。此外,更改图像需要花费大量时间,具体取决于图像的大小。
如果有人可以给我一些不同的方法来了解我的工作方式,我将不胜感激。
上传到Firestore的函数:
File _image;
Future getImage(bool gallery) async {
ImagePicker picker = ImagePicker();
PickedFile pickedFile;
// Let user select photo from gallery
if (gallery) {
pickedFile = await picker.getImage(
source: ImageSource.gallery,
);
}
setState(() {
if (pickedFile != null) {
_image = File(pickedFile.path);
uploadFile(_image);
uploadToFirebase(); // Use if you only need a single picture
} else {
print('No image selected.');
}
});
}
Future<String> uploadFile(File image) async {
String downloadURL;
Reference ref = FirebaseStorage.instance
.ref()
.child("images/${_firebaseAuth.currentUser.uid}");
await ref.putFile(image);
downloadURL = await ref.getDownloadURL();
return downloadURL;
}
Future uploadToFirebase() async {
final CollectionReference users =
_firebaseFirestore.collection("Companies");
final String uid = _firebaseAuth.currentUser.uid;
String url = await uploadFile(
_image); // this will upload the file and store url in the variable 'url'
await users.doc(uid).update({'url': url});
final result = await users.doc(uid).get();
return result.data()["url"];
}
我显示图片的代码:
Container(
child: _image != null
? Column(
children: [
StreamBuilder(
stream: _firebaseFirestore
.collection("Companies")
.doc(_firebaseAuth
.currentUser.uid)
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Text("Loading");
}
return Image.network(
snapshot.data.data()["url"],
width: 100,
height: 100,
);
},
),
],
)
: Container(
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius:
BorderRadius.circular(50),
),
width: 100,
height: 100,
child: Icon(
Icons.camera_alt,
color: Colors.grey[800],
),
),
),
首先,在您的代码中,您上传文件两次:一次在 setState() 中,另一次在 uploadToFirebase() 中;
当 snapshot.connectionState 与 connectionState.done 不同时,您可以尝试显示加载文本:
if (!snapshot.hasData) {
return Text("Loading");
}
return Image.network(
snapshot.data.data()["url"],
width: 100,
height: 100,
);
编辑:你能告诉我这是否有效吗?
File _image;
bool _loading = false;
final FirebaseStorage _storage = FirebaseStorage(storageBucket:'gs://LINK.com'); //find your link in your storage console like this screenshot https://i.imgur.com/gW35HJk.png
StorageUploadTask _uploadTask;
Future getImage(bool gallery) async {
this.setState((){
_loading = true;
});
ImagePicker picker = ImagePicker();
PickedFile pickedFile;
// Let user select photo from gallery
if (gallery) {
pickedFile = await picker.getImage(
source: ImageSource.gallery,
);
}
setState(() {
if (pickedFile != null) {
_image = File(pickedFile.path);
uploadFile(_image);
} else {
print('No image selected.');
this.setState((){
_loading = false;
});
}
});
}
Future<String> uploadFile(File image) async {
String downloadURL;
String filePath = "images/${_firebaseAuth.currentUser.uid}";
setState(() {
_uploadTask = _storage.ref().child(filePath).putFile(image).onComplete;
});
var imageUrl = await (await
_uploadTask.onComplete).ref.getDownloadURL();
downloadURL = imageUrl.toString();
uploadToFirebase(downloadURL);
}
Future uploadToFirebase(downloadURL) async {
final CollectionReference users =
_firebaseFirestore.collection("Companies");
final String uid = _firebaseAuth.currentUser.uid;
String url = downloadURL // this will upload the file and store url in the variable 'url'
await users.doc(uid).update({'url': url});
final result = await users.doc(uid).get();
if (result != null) {
setState((){
getImage().onComplete{
loading = false;
}
return result.data()["url"];
}
});
}
----------Below is before edit---------------
Use a bool to determine if loading is complete or not
bool _loading = false;
Future getImage(bool gallery) async {
this.setState((){
_loading = true;
});
ImagePicker picker = ImagePicker();
PickedFile pickedFile;
// Let user select photo from gallery
if (gallery) {
pickedFile = await picker.getImage(
source: ImageSource.gallery,
);
}
setState(() {
if (pickedFile != null) {
_image = File(pickedFile.path);
uploadFile(_image);
uploadToFirebase(); // Use if you only need a single picture'
setState(() {
_loading = false;
});
} else {
print('No image selected.');
setState(() {
_loading = false;
});
}
});
}
我有一个带有个人资料页面的应用程序,我想在其中有一张个人资料图片,用户可以随时更新。
我现在拥有的代码执行以下操作:StreamBuilder 将获取包含当前用户 UID 的 Firestore 集合,并构建一个 Image.network 获取文档“URL”来自 snapshot.data.
问题:
第一次,当用户创建新用户时,我在图像上有一个占位符,当用户从图库中选择新图像时,它会 return 更新之间的时间错误收集并更新 UI,然后更改为新图像。此外,更改图像需要花费大量时间,具体取决于图像的大小。
如果有人可以给我一些不同的方法来了解我的工作方式,我将不胜感激。
上传到Firestore的函数:
File _image;
Future getImage(bool gallery) async {
ImagePicker picker = ImagePicker();
PickedFile pickedFile;
// Let user select photo from gallery
if (gallery) {
pickedFile = await picker.getImage(
source: ImageSource.gallery,
);
}
setState(() {
if (pickedFile != null) {
_image = File(pickedFile.path);
uploadFile(_image);
uploadToFirebase(); // Use if you only need a single picture
} else {
print('No image selected.');
}
});
}
Future<String> uploadFile(File image) async {
String downloadURL;
Reference ref = FirebaseStorage.instance
.ref()
.child("images/${_firebaseAuth.currentUser.uid}");
await ref.putFile(image);
downloadURL = await ref.getDownloadURL();
return downloadURL;
}
Future uploadToFirebase() async {
final CollectionReference users =
_firebaseFirestore.collection("Companies");
final String uid = _firebaseAuth.currentUser.uid;
String url = await uploadFile(
_image); // this will upload the file and store url in the variable 'url'
await users.doc(uid).update({'url': url});
final result = await users.doc(uid).get();
return result.data()["url"];
}
我显示图片的代码:
Container(
child: _image != null
? Column(
children: [
StreamBuilder(
stream: _firebaseFirestore
.collection("Companies")
.doc(_firebaseAuth
.currentUser.uid)
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Text("Loading");
}
return Image.network(
snapshot.data.data()["url"],
width: 100,
height: 100,
);
},
),
],
)
: Container(
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius:
BorderRadius.circular(50),
),
width: 100,
height: 100,
child: Icon(
Icons.camera_alt,
color: Colors.grey[800],
),
),
),
首先,在您的代码中,您上传文件两次:一次在 setState() 中,另一次在 uploadToFirebase() 中;
当 snapshot.connectionState 与 connectionState.done 不同时,您可以尝试显示加载文本:
if (!snapshot.hasData) {
return Text("Loading");
}
return Image.network(
snapshot.data.data()["url"],
width: 100,
height: 100,
);
编辑:你能告诉我这是否有效吗?
File _image;
bool _loading = false;
final FirebaseStorage _storage = FirebaseStorage(storageBucket:'gs://LINK.com'); //find your link in your storage console like this screenshot https://i.imgur.com/gW35HJk.png
StorageUploadTask _uploadTask;
Future getImage(bool gallery) async {
this.setState((){
_loading = true;
});
ImagePicker picker = ImagePicker();
PickedFile pickedFile;
// Let user select photo from gallery
if (gallery) {
pickedFile = await picker.getImage(
source: ImageSource.gallery,
);
}
setState(() {
if (pickedFile != null) {
_image = File(pickedFile.path);
uploadFile(_image);
} else {
print('No image selected.');
this.setState((){
_loading = false;
});
}
});
}
Future<String> uploadFile(File image) async {
String downloadURL;
String filePath = "images/${_firebaseAuth.currentUser.uid}";
setState(() {
_uploadTask = _storage.ref().child(filePath).putFile(image).onComplete;
});
var imageUrl = await (await
_uploadTask.onComplete).ref.getDownloadURL();
downloadURL = imageUrl.toString();
uploadToFirebase(downloadURL);
}
Future uploadToFirebase(downloadURL) async {
final CollectionReference users =
_firebaseFirestore.collection("Companies");
final String uid = _firebaseAuth.currentUser.uid;
String url = downloadURL // this will upload the file and store url in the variable 'url'
await users.doc(uid).update({'url': url});
final result = await users.doc(uid).get();
if (result != null) {
setState((){
getImage().onComplete{
loading = false;
}
return result.data()["url"];
}
});
}
----------Below is before edit---------------
Use a bool to determine if loading is complete or not
bool _loading = false;
Future getImage(bool gallery) async {
this.setState((){
_loading = true;
});
ImagePicker picker = ImagePicker();
PickedFile pickedFile;
// Let user select photo from gallery
if (gallery) {
pickedFile = await picker.getImage(
source: ImageSource.gallery,
);
}
setState(() {
if (pickedFile != null) {
_image = File(pickedFile.path);
uploadFile(_image);
uploadToFirebase(); // Use if you only need a single picture'
setState(() {
_loading = false;
});
} else {
print('No image selected.');
setState(() {
_loading = false;
});
}
});
}