I have a simple app page where when user clicks on the button, the score goes up by one. I use a stream to show the updated score on the page to the user. How can I cancel this steam. I'm asking due to the fact that when I try to logout, using firebase, I get an error, which is caused due to the stream still being opened.
How can I close the stream when user clicks the logout button without it causing an error?
clickerPage.dart
// ignore_for_file: file_names
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:poop_alert/model/user_model.dart';
import 'package:flutter/material.dart';
import 'package:poop_alert/navDraw.dart';
class poopClicker extends StatefulWidget {
@override
State<poopClicker> createState() => _poopClickerState();
}
class _poopClickerState extends State<poopClicker> {
User? user = FirebaseAuth.instance.currentUser;
UserModel loggedInUser = UserModel();
String userID = '';
var count = 0;
@override
void initState() {
super.initState();
FirebaseFirestore.instance
.collection("users")
.doc(user!.uid)
.get()
.then((value) {
loggedInUser = UserModel.fromMap(value.data());
setState(() {});
//int poopClick = loggedInUser.score;
});
}
getuserData() async {
User? getuserID = FirebaseAuth.instance.currentUser;
userID = getuserID!.uid;
print(userID);
}
CollectionReference note = FirebaseFirestore.instance.collection('user');
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[200],
drawer: NavigationDrawerWidget(),
appBar: AppBar(
title: const Text('PoopAlert'),
centerTitle: true,
backgroundColor: Color(0xff839ae3),
elevation: 0.0,
),
body: Column(
children: [
SizedBox(height: 100),
Center(
child: StreamBuilder(
stream: showScore(),
builder: (context, snapshot) {
if (snapshot.data != null) {
return Center(
child: Text(
'Score: ' snapshot.data.toString(),
style: TextStyle(
color: Color(0xff516395),
fontSize: 30.0,
letterSpacing: 2.0,
fontWeight: FontWeight.bold,
),
),
);
} else {
return Text(
'Score: 0',
style: TextStyle(
color: Color(0xff516395),
fontSize: 30.0,
letterSpacing: 2.0,
fontWeight: FontWeight.bold,
)
);
}
},
),
),
Center(
child: ElevatedButton(
onPressed: () {
print("clicked");
},
child: IconButton(
icon: Image.asset('assets/poop.png'),
iconSize: 300,
onPressed: () {
getuserData();
setState(() {
print('Clicked: ' "${loggedInUser.score}");
FirebaseFirestore.instance
.collection('users')
.doc(loggedInUser.uid)
.update({"score": FieldValue.increment(1)});
});
},
),
style: ElevatedButton.styleFrom(
primary: Colors.grey[200], elevation: 0.0),
),
),
],
),
);
}
Stream<int?> showScore() async* {
FirebaseFirestore.instance
.collection("users")
.doc(user!.uid)
.get()
.then((value) {
loggedInUser = UserModel.fromMap(value.data());
setState(() {});
});
yield loggedInUser.score;
}
}
``
CodePudding user response:
You should listen to the score directly from the StreamBuilder
.
StreamBuilder<DocumentSnapshot<Map<String, dynamic>>>(
stream: FirebaseFirestore.instance
.collection("users")
.doc(user!.uid)
.snapshots(),
builder: ((context, snapshot) {
loggedInUser = UserModel.fromMap(snapshot.data!.data()!);
// some code omitted
return Center(
child: Text(
'Score: ' loggedInUser.score.toString(),
// rest of your code
),
);
}),
)
CodePudding user response:
Thank you everyone for all your help, but after sometime I finally got it working. Instead of mapping all the values to my class I instead just called for my specifci value from snapshop.data
StreamBuilder<
DocumentSnapshot<Map<String, dynamic>>>(
stream: FirebaseFirestore.instance
.collection("users")
.doc(user!.uid)
.snapshots(),
builder: ((context, snapshot) {
print(snapshot.data);
var userDocument = snapshot.data;
if (snapshot.data != null) {
return Center(
child: Text(
snapshot.data!["timeActive"].toString(),
style: TextStyle(
color: Color(0xff516395),
fontSize: 30.0,
letterSpacing: 2.0,
fontWeight: FontWeight.bold,
),
),
);
} else {
return Text('0',
style: TextStyle(
color: Color(0xff516395),
fontSize: 30.0,
letterSpacing: 2.0,
fontWeight: FontWeight.bold,
));
}
}),
)