如何更新 Storage 中的图片并刷新 Streambuilder 以显示新图片?
How to update picture in Storage and refresh Streambuilder to show the new picture?
我在 Flutter 应用程序中遇到更新个人资料图片的问题。我已经显示了当前登录用户的详细信息,如下所示:
body: StreamBuilder<Object>(
stream: FirebaseFirestore.instance
.collection('users')
.doc(loggedInUser)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
} else if (snapshot.data != null) {
final userData = snapshot.data as DocumentSnapshot;
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
decoration: BoxDecoration(
color: Colors.grey[200],
),
width: MediaQuery.of(context).size.width / 1,
height: MediaQuery.of(context).size.width / 2.5,
child: CachedNetworkImage(
imageUrl: '${userData['image']}',
imageBuilder: (context, imageProvider) => Container(
width: 120,
height: 120,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: imageProvider,
),
),
),
placeholder: (context, url) =>
Center(child: CircularProgressIndicator()),
errorWidget: (context, url, error) => Icon(Icons.error),
),
),
Container(
margin: EdgeInsets.symmetric(horizontal: 10),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(height: 40),
Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 10),
child: Text("Name : ",
style: TextStyle(
fontSize: 18,
color: Colors.black54,
fontWeight: FontWeight.w500)),
),
Padding(
padding: const EdgeInsets.fromLTRB(60, 0, 0, 0),
child: Text('${userData['fullName']}',
style: TextStyle(
fontSize: 18,
color: Colors.black54,
fontWeight: FontWeight.w500)),
)
],
),
SizedBox(height: 20),
],
),
),
],
);
} else
return Text('null');
})
为了在新的“编辑个人资料”页面中更新个人资料图片,我编写的代码是:
postNewProfilePicture(String userid) async {
final ref =
FirebaseStorage.instance.ref().child('users').child(userid + '.jpg');
await ref.putFile(newprofilePic!);
String url = await ref.getDownloadURL();
newUploadedProfilePic = url;
}
ElevatedButton(
style: ElevatedButton.styleFrom(
padding: EdgeInsets.symmetric(
horizontal: 45, vertical: 10),
textStyle: TextStyle(
fontWeight: FontWeight.w500,
color: Colors.white,
fontSize: 15)),
onPressed: () {
postNewProfilePicture(widget.id);
if (_formKey.currentState!.validate()) {
updateUser(widget.id, name, newUploadedProfilePic);
}
Navigator.of(context).pop();
},
child: Text(
'Update',
style: TextStyle(fontSize: 15),
),
),
Future<void> updateUser(id, name, newimage) {
return users
.doc(id)
.update({
'fullName': name,
'image': newimage
})
.then((value) => print('Success'))
.catchError((error) => print('Error: $error'));
}
使用这些代码,上传的新图片的 url 有时会成功插入到 Firestore 中,但其他时候只会收到 null。在新个人资料图片成功的情况下,我的应用程序也只显示旧个人资料图片。如何才能成功插入新图片并加载显示?
“更新”是针对一个字段的。将 set 与选项 merge true 结合使用。
Future<void> updateUser(id, name, newimage) {
return users
.doc(id)
.set({
'fullName': name,
'image': newimage
}, SetOptions(merge: true))
.then((value) => print('Success'))
.catchError((error) => print('Error: $error'));
}
尝试添加模型 MyUser
@immutable
class MyUser {
final String id;
final String fullName;
final String image;
const MyUser({required this.id, required this.fullName, required this.image});
Map<String, dynamic> toMap() {
return {
'id': id,
'fullName': fullName,
'image': image,
};
}
factory MyUser.fromMap(Map<String, dynamic>? map) {
if (map == null) {
return const MyUser(id: "", fullName: "", image: "");
}
return MyUser(
id: map['id'] as String,
fullName: map['fullName'] as String,
image: map['image'] as String,
);
}
}
然后在您的流生成器中像这样获取您的图像
StreamBuilder<MyUser>(
stream: FirebaseFirestore.instance
.collection('users')
.doc(loggedInUser)
.snapshots()
.map((map) => MyUser.fromMap(map.data())),
builder: (context, snapshot) {
final myUser = snapshot.data;
if(myUser == null){
return const Center(
child: CircularProgressIndicator(),
);
}
print(myUser.image);
return Container();
})
我在 Flutter 应用程序中遇到更新个人资料图片的问题。我已经显示了当前登录用户的详细信息,如下所示:
body: StreamBuilder<Object>(
stream: FirebaseFirestore.instance
.collection('users')
.doc(loggedInUser)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
} else if (snapshot.data != null) {
final userData = snapshot.data as DocumentSnapshot;
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
decoration: BoxDecoration(
color: Colors.grey[200],
),
width: MediaQuery.of(context).size.width / 1,
height: MediaQuery.of(context).size.width / 2.5,
child: CachedNetworkImage(
imageUrl: '${userData['image']}',
imageBuilder: (context, imageProvider) => Container(
width: 120,
height: 120,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: imageProvider,
),
),
),
placeholder: (context, url) =>
Center(child: CircularProgressIndicator()),
errorWidget: (context, url, error) => Icon(Icons.error),
),
),
Container(
margin: EdgeInsets.symmetric(horizontal: 10),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(height: 40),
Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 10),
child: Text("Name : ",
style: TextStyle(
fontSize: 18,
color: Colors.black54,
fontWeight: FontWeight.w500)),
),
Padding(
padding: const EdgeInsets.fromLTRB(60, 0, 0, 0),
child: Text('${userData['fullName']}',
style: TextStyle(
fontSize: 18,
color: Colors.black54,
fontWeight: FontWeight.w500)),
)
],
),
SizedBox(height: 20),
],
),
),
],
);
} else
return Text('null');
})
为了在新的“编辑个人资料”页面中更新个人资料图片,我编写的代码是:
postNewProfilePicture(String userid) async {
final ref =
FirebaseStorage.instance.ref().child('users').child(userid + '.jpg');
await ref.putFile(newprofilePic!);
String url = await ref.getDownloadURL();
newUploadedProfilePic = url;
}
ElevatedButton(
style: ElevatedButton.styleFrom(
padding: EdgeInsets.symmetric(
horizontal: 45, vertical: 10),
textStyle: TextStyle(
fontWeight: FontWeight.w500,
color: Colors.white,
fontSize: 15)),
onPressed: () {
postNewProfilePicture(widget.id);
if (_formKey.currentState!.validate()) {
updateUser(widget.id, name, newUploadedProfilePic);
}
Navigator.of(context).pop();
},
child: Text(
'Update',
style: TextStyle(fontSize: 15),
),
),
Future<void> updateUser(id, name, newimage) {
return users
.doc(id)
.update({
'fullName': name,
'image': newimage
})
.then((value) => print('Success'))
.catchError((error) => print('Error: $error'));
}
使用这些代码,上传的新图片的 url 有时会成功插入到 Firestore 中,但其他时候只会收到 null。在新个人资料图片成功的情况下,我的应用程序也只显示旧个人资料图片。如何才能成功插入新图片并加载显示?
“更新”是针对一个字段的。将 set 与选项 merge true 结合使用。
Future<void> updateUser(id, name, newimage) {
return users
.doc(id)
.set({
'fullName': name,
'image': newimage
}, SetOptions(merge: true))
.then((value) => print('Success'))
.catchError((error) => print('Error: $error'));
}
尝试添加模型 MyUser
@immutable
class MyUser {
final String id;
final String fullName;
final String image;
const MyUser({required this.id, required this.fullName, required this.image});
Map<String, dynamic> toMap() {
return {
'id': id,
'fullName': fullName,
'image': image,
};
}
factory MyUser.fromMap(Map<String, dynamic>? map) {
if (map == null) {
return const MyUser(id: "", fullName: "", image: "");
}
return MyUser(
id: map['id'] as String,
fullName: map['fullName'] as String,
image: map['image'] as String,
);
}
}
然后在您的流生成器中像这样获取您的图像
StreamBuilder<MyUser>(
stream: FirebaseFirestore.instance
.collection('users')
.doc(loggedInUser)
.snapshots()
.map((map) => MyUser.fromMap(map.data())),
builder: (context, snapshot) {
final myUser = snapshot.data;
if(myUser == null){
return const Center(
child: CircularProgressIndicator(),
);
}
print(myUser.image);
return Container();
})