I have a streambuilder that Im trying to call a function that updates the read status on my app
void readMessage() async {
int num = 0;
final query = await FirebaseFirestore.instance
.collection('chats')
.doc(chatroomId(FirebaseAuth.instance.currentUser!.uid, widget.uid))
.collection('messages')
.where('uid', isEqualTo: widget.uid)
.where('read', isEqualTo: false)
.get();
query.docs.forEach((doc) {
doc.reference.update({'read': true});
});
num = query.docs.length;
await FirebaseFirestore.instance
.collection('users')
.doc(FirebaseAuth.instance.currentUser!.uid)
.update(
{"messagesNotification": FieldValue.increment(-num)},
);
}
and in my streambuilder im trying
return Container(
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('chats')
.doc(chatRoom)
.collection('messages')
.orderBy('createdAt', descending: true)
.snapshots(),
builder: (context,
AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> snapshot) {
readMessage();
The issue is that it seems to be running twice, so if for example they have 3 unread messages its decreasing the message counter by 3 then 3 again. Im also not sure if this is how it works but am I right in believing that if a new message appeared in the stream it will run that method everytime so that incoming messages are marked as read when the stream is open?
CodePudding user response:
StreamBuilder
widget rebuilds the ui with every change with the stream, so you need to wrap your readMessage()
with conditional statement to decide whether to run this function or not
CodePudding user response:
You could create a boolean to check if the function is called
bool functionCalled = false;
Check if the function is called and if not you do your logic and inside it you set it to true. The next call won't jump in the if.
if(!functionCalled){
functionCalled = true;
int num = 0;
final query....
}