我使用StreamProvider从本教程中进行了复制:https://github.com/iamshaunjp/flutter-firebase
我有一个单独的课程,像这样:
class PostItem extends StatefulWidget {
PostItem({Key key, @required this.post}) : super(key: key);
final Post post;
@override
_PostItemState createState() => _PostItemState();
}
class _PostItemState extends State<PostItem> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return getCard(context);
}
Widget getCard(context) {
return Card(
child: InkWell(
onTap: _didSelectItem,
child: Row(
children: [
_textColumn(context),
_voteColumn(context),
],
),
),
);
}
Widget _textColumn(context) {
return Expanded(
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
child: Text(
widget.post.title,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0),
),
padding: const EdgeInsets.fromLTRB(16, 16, 0, 0),
),
BottomButtonBar(
onLikedPressed: () => _didLikePost(),
// likeColor: _likedPids.contains(widget.post.pid)
// ? Theme.of(context).primaryColor
// : Theme.of(context).accentColor,
),
],
),
),
);
}
Widget _voteColumn(context) {
final user = Provider.of<User>(context);
final post = widget.post;
return VoteColumn(
upArrowColor:
Vote.getVote(user.uid, post.upvoteUids, post.downvoteUids) ==
Vote.up
? Theme.of(context).primaryColor
: Theme.of(context).focusColor,
downArrowColor:
Vote.getVote(user.uid, post.upvoteUids, post.downvoteUids) ==
Vote.down
? Theme.of(context).primaryColor
: Theme.of(context).focusColor,
didVote: (val) => _didVote(val),
value: widget.post.upvoteUids.length - widget.post.downvoteUids.length);
}
//Mark: Private
_didLikePost() {
print("called");
setState(() {});
// _dbLikePost();
}
_dbLikePost() async {
// final userMetadata = Provider.of<UserMetadata>(context);
// try {
// Database().updateUserMetadata(userMetadata);
// } catch (error) {
// print(error);
// } finally {}
}
_didSelectItem() {
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => Comments(post: widget.post),
),
);
}
//true for up, false for down
_didVote(bool newVote) {
setState(() {
_locatUpdate(newVote);
});
_dbUpdate();
}
_locatUpdate(newVote) {
final user = Provider.of<User>(context);
final uid = user.uid;
final post = widget.post;
switch (Vote.getVote(user.uid, post.upvoteUids, post.downvoteUids)) {
case Vote.up:
if (newVote) {
post.upvoteUids.remove(uid);
} else {
post.upvoteUids.remove(uid);
post.downvoteUids.add(uid);
}
break;
case Vote.down:
if (newVote) {
post.downvoteUids.remove(uid);
post.upvoteUids.add(uid);
} else {
post.downvoteUids.remove(uid);
}
break;
case Vote.none:
if (newVote) {
post.upvoteUids.add(uid);
} else {
post.downvoteUids.add(uid);
}
break;
}
}
_dbUpdate() async {
try {
await Database().post(widget.post);
} catch (error) {
print(error);
} finally {}
}
}
在这里,我感到非常困惑。我可以更改widget.post并调用setState,它可以完美运行。我还可以使用widget.post更新数据库中的帖子。如我所料,效果很好。
现在,我想更新已放在上面流中的userMetadata。
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
return user == null
? MaterialWidget(home: AuthView())
: StreamProvider<UserMetadata>.value(
value: Database(id: user.uid).userMetadata,
catchError: (_, error) => UserMetadata(uid: ""),
child: MaterialWidget(
home: Home(
title: "Siren",
),
),
);
}
我只想设置PostItem页面的状态,并在单击like按钮时更改db。我想使用流提供程序中的UserMeta来执行此操作。但是,如果尝试执行此操作,则会收到错误消息“不支持的操作:无法添加到无法修改的列表”。为什么在尝试编辑流提供程序时却出现此错误,而对于帖子却没有?编辑列表,将setState设置到位然后推送到数据库的正确方法是什么?