Flutter Firebase:Firebase 中的数据更新,但未在屏幕上自动显示计数器更新
Posted
技术标签:
【中文标题】Flutter Firebase:Firebase 中的数据更新,但未在屏幕上自动显示计数器更新【英文标题】:Flutter Firebase: data updating in Firebase, but not showing the counter update on the screen automatically 【发布时间】:2021-06-19 15:02:39 【问题描述】:我的 Firebase 中有一个计数器,用于保存一张图片的总投票数。当按下 upvote 按钮时,数据库应该将指定计数器的计数器更新 1,它会这样做。但是,它不会在应用程序屏幕上显示更新。例如,如果一张图片有 8 个赞,并且按下按钮进行赞,它仍然会在屏幕上显示 8 个赞,但在数据库中它现在将是 9 个赞。当我热刷新时,值会发生变化。我怎样才能让这两件事异步发生?我尝试过使用它,它总是更新数据库并且屏幕保持不变,或者屏幕改变并且数据库没有。
对于下面的函数,它们的行为符合预期,但在屏幕上不是异步的。
数据库中增加关注者的相关函数:
// likedposts is a list of posts that have already been liked and is initalised earlier
// even if I remove the if statement here, the behaviour is the same
void incrementFollowers(int index) async
if (!likedposts.contains(posts[index]))
likedposts.add(posts[index]);
addLikedPost();
FirebaseFirestore.instance
.collection('uploads')
.doc(usernames[index])
.collection('images')
.where('caption', isEqualTo: captions[index])
.get()
.then((querySnapshot)
querySnapshot.docs.forEach((result) async
FirebaseFirestore.instance
.collection('uploads')
.doc(usernames[index])
.collection('images')
.doc(result.id)
.update('upvotes': upvotes[index]+1,);
setState(()
getUpvotes(index);
);
);
);
显示赞成票的功能:
getUpvotes(int index)
return RichText(
text: TextSpan(
style:
TextStyle(color: Colors.black, fontSize: 20.0),
children: <TextSpan>[
TextSpan(
text: upvotes[index].toString() + ' upvotes',
style: TextStyle(color: Colors.blue),
recognizer: TapGestureRecognizer()
..onTap = ()
print(
'This will take to upvoters of the photo');
),
]));
在我的应用中显示所有内容的小部件(要找到我调用 incrementFollowers 按钮的位置,只需对 incrementFollowers 执行 ctrl+F 即可找到它):
Widget _getPost()
Size size = MediaQuery.of(context).size;
if (url!= null)
return new ListView.builder(
itemCount: images.length,
itemBuilder: (BuildContext context, int userIndex)
return Container(
child: Column(
children: <Widget>[
Container(
//Includes dp + username + report flag
margin: EdgeInsets.all(10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
children: <Widget>[
Container(
margin: EdgeInsets.only(right: 8),
child: GestureDetector(
onTap: ()
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => UserProfile(usernames[userIndex])
),
);
,
child: CircleAvatar(
backgroundImage: displayPic[1],
))),
RichText(
text: TextSpan(children: <TextSpan>[
TextSpan(
text: usernames[userIndex],
style: TextStyle(
color: Colors.black, fontSize: 15.0),
recognizer: TapGestureRecognizer()
..onTap = ()
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => UserProfile(usernames[userIndex])
),
);
)
]),
)
],
),
IconButton(
icon: Image.asset('assets/pictures/ICON_flag.png'),
iconSize: 25,
onPressed: ()
reportUser(userIndex, context);
,
),
],
),
),
Stack(children: <Widget>[
Container(
//the post picture
child: GestureDetector(
//This is to handle the tagged users raised button
onTap: ()
if (isVisible == false)
setState(()
isVisible = true;
);
else
setState(()
isVisible = false;
);
,
),
height: size.height * 0.5,
width: returnWidth(),
padding: EdgeInsets.only(
left: 16,
right: 16,
top: 0,
bottom: 24,
),
// constraints: BoxConstraints(maxHeight: 50),
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.fill, image: NetworkImage(images[userIndex])),
)
),
Positioned(
top: 25,
left: 50,
child: returnTaggedUsers(userIndex),)
]),
Row(
mainAxisAlignment: returnAlignment(),
// upvote + downvote + comment + send + save icons
children: <Widget>[
Container(
color: upVoted ? Colors.blue : Colors.white,
margin: EdgeInsets.only(right: 8),
child: IconButton(
icon: Image.asset('assets/pictures/ICON_upvote.png'),
iconSize: 25,
onPressed: () async
setState(()
incrementFollowers(userIndex);
);
getUpvotes(userIndex);
,
)
),
Container(
color: downVoted ? Colors.blue : Colors.white,
margin: EdgeInsets.only(right: 8),
child: IconButton(
icon: Image.asset('assets/pictures/ICON_downvote.png'),
iconSize: 25,
onPressed: ()
setState(()
downVoted = true;
upVoted = false;
);
,
)),
Container(
margin: EdgeInsets.only(right: 8),
child: IconButton(
icon: Image.asset('assets/pictures/ICON_comment.png'),
iconSize: 25,
onPressed: ()
commentPopUp(userIndex, context);
,
)),
Container(
margin: EdgeInsets.only(right: 8),
child: IconButton(
icon: Image.asset('assets/pictures/ICON-send.png'),
iconSize: 25,
onPressed: ()
print(
'This will let a user send the post to another user');
,
)),
Container(
margin: EdgeInsets.only(right: 8),
child: IconButton(
icon: Image.asset('assets/pictures/ICON_save.png'),
iconSize: 25,
onPressed: ()
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ReportPanel()
),
);
,
)),
],
),
Column(
mainAxisAlignment: returnAlignment(),
//This column contains username, upload description and total upvotes
children: <Widget>[
Container(
//The person who posted along with photo description
alignment: returnCommentAlignment(),
margin: EdgeInsets.only(left: 10, right: 10),
child: RichText(
text: TextSpan(
style:
TextStyle(color: Colors.black, fontSize: 20.0),
children: <TextSpan>[
TextSpan(
text: usernames[userIndex] + ': ',
style: TextStyle(color: Colors.blue),
recognizer: TapGestureRecognizer()
..onTap = ()
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => UserProfile(usernames[userIndex])
),
);
),
TextSpan(text: captions[userIndex]),
])),
),
Container(
//The total upvotes of post
alignment: returnCommentAlignment(),
margin: EdgeInsets.only(left: 10, right: 10),
child: getUpvotes(userIndex),
)
],
),
Column(
mainAxisAlignment: returnAlignment(),
//This column contains username and comment of commenters
children: <Widget>[
Container(
//First comment
alignment: returnCommentAlignment(),
margin: EdgeInsets.only(left: 10, right: 10),
child: RichText(
text: TextSpan(
style:
TextStyle(color: Colors.black, fontSize: 20.0),
children: <TextSpan>[
TextSpan(
text:
'HarperEvans1: ', //will be a username from firebase
style: TextStyle(color: Colors.blue),
recognizer: TapGestureRecognizer()
..onTap = ()
print(
'This will take to profile of that person');
),
TextSpan(text: 'Nice photo!'),
])),
),
Container(
//Second comment
alignment: returnCommentAlignment(),
margin: EdgeInsets.only(left: 10, right: 10),
child: RichText(
text: TextSpan(
style:
TextStyle(color: Colors.black, fontSize: 20.0),
children: <TextSpan>[
TextSpan(
text:
'trevorwilkinson: ', //will be a username from firebase
style: TextStyle(color: Colors.blue),
recognizer: TapGestureRecognizer()
..onTap = ()
print(
'This will take to profile of that person');
),
TextSpan(
text:
'Panda Panda Panda Panda Panda Panda Panda Panda Panda Panda Panda Panda Panda Panda'),
])),
),
Container(
//view more comments
alignment: returnCommentAlignment(),
margin: EdgeInsets.only(left: 10, right: 10),
child: RichText(
text: TextSpan(
style:
TextStyle(color: Colors.grey, fontSize: 20.0),
children: <TextSpan>[
TextSpan(
text:
'view more comments', //will take to the comments
style: TextStyle(color: Colors.grey),
recognizer: TapGestureRecognizer()
..onTap = ()
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CommentPage(posts[userIndex], usernames[userIndex])
),
);
),
])),
)
],
)
],
));
);
谢谢!
【问题讨论】:
【参考方案1】:目前,您没有任何东西可以触发 Firebase 的重建。您需要在 getUpvotes
函数中返回 FutureBuilder
或 StreamBuilder
。这将收到有关云中更改的通知并触发重新构建。
这里有一些东西可以帮助您入门。而是在您的 getUpvotes
方法中返回它并完成 StreamBuilder
的流部分
StreamBuilder(
stream: Firestore.instance.collection...// finish this part to get your snapshot of total upvotes from your collection,
builder: (context, snapshot)
if(snapshot.hasData)
return RichText(
text: TextSpan(
style: TextStyle(color: Colors.black, fontSize: 20.0),
children: <TextSpan>[
TextSpan(
text: upvotes[index].toString() + ' upvotes',
style: TextStyle(color: Colors.blue),
recognizer: TapGestureRecognizer()
..onTap = ()
print('This will take to upvoters of the photo');
),
],
),
);
else
// handle no data
,
);
【讨论】:
您好,感谢您的评论。所以我试着按照你说的做,但是行为仍然是一样的;数据库更新,但屏幕不会直到我热刷新或者我进入另一个页面并返回它。这是我在流中添加的内容:流:FirebaseFirestore.instance.collection('uploads') .doc(usernames[index]).collection('images').snapshots(),但它仍然不会异步更新小部件。我做错什么了吗?提前致谢 刚刚注意到一些更奇怪的行为。如果您查看我上面的 incrementFollowers 函数,您会看到以下行:.update('upvotes': upvotes[index]+1,);
。这使得数据库更新,但小部件没有。但如果我这样做:.update('upvotes': upvotes[index]++,);
,小部件会正确更新,但数据库不会。不知道为什么会这样
玩弄了你的解决方案,我明白了。非常感谢!以上是关于Flutter Firebase:Firebase 中的数据更新,但未在屏幕上自动显示计数器更新的主要内容,如果未能解决你的问题,请参考以下文章
Flutter 和 Firebase:任务 ':firebase_auth:compileDebugJavaWithJavac' 执行失败
Flutter - 将 Firebase 通知推送给没有 Firebase 身份验证的特定用户
Flutter 和 Firebase:从 Firebase 中的数组中删除项目(地图)
Flutter : getDownloadUrl (firebase 存储)