Am I thinking about this the right way?
I created a function that takes in a value from firebase, value in seconds, and convert it into hours:minutes:seconds, this works fine. I've used Streams for my function and a StreamBuilder for my text widget to display the value, but without the setState I don't know how else to always show the more recent value while the user is actively looking at the page. Without setState I would have to navigate to a different page then come back to see the UI update the most recent value.
Is using setState the correct way to go about it? Will it cause a spam of writes to firebase, causing me to go over the limit ( i have a free firebase account).
Is there a better way to always show the most updated value on screen?
Stream<String> printDuration() async* {
FirebaseFirestore.instance
.collection("users")
.doc(user!.uid)
.snapshots()
.listen(
(event) => someVar = event.data()!['timeActive'],
one rror: (error) => print("Listen failed: $error")
);
Duration duration = Duration(seconds: someVar ?? loggedInUser.timeActive);
String twoDigits(int n) => n.toString().padLeft(2, "0");
String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60));
String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60));
String _getData = "${twoDigits(duration.inHours)}:$twoDigitMinutes:$twoDigitSeconds";
setState(() {});
yield _getData;
}
text widget
StreamBuilder<String>(
stream: printDuration(),
builder: ((context, snapshot) {
if (snapshot.data != null) {
return Center(
child: Text(
snapshot.hasData ? snapshot.data!.toString(): 'no data yet',
style: TextStyle(
color: Color(0xff516395),
fontSize: 26.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,
));
}
}),
)
CodePudding user response:
No need to call setState
, StreamBuilder
builds itself on the latest update. Try something like this.
Stream<String> timeActive(String userUid) {
return FirebaseFirestore.instance
.collection("users")
.doc(userUid)
.snapshots()
.map((e) => e.data()?['timeActive']);
.map((timeActive) { <convert to hours:minutes:seconds> });
}