I have a Future which takes a value from my Cloud Firestore database and displays an icon in the body of my app. If the value in the database changes, the icon updates. I have been using setState to rebuild my widget tree and this works fine - the app reacts almost instantly to changes in my Cloud Firestore database. This is great! Code:
Future<void> takenSurvey2() async {
final sn = await Firestore.instance
.collection('Controller')
.document('Current Survey')
.get();
surveyName2 = sn['cs'];
final snapShot = await Firestore.instance
.collection('$surveyName2' + '_entrants')
.document(userid)
.get();
if (snapShot.exists) {
takenSurvey = true;
} else {
takenSurvey = false;
}
setState(() {});
}
and the place where the icon is shown is coded like this (within a stack):
Positioned(
right: 30,
top: 20,
child: FutureBuilder(
future: takenSurvey2(),
builder: (context, snapshot) {
if (takenSurvey == false) {
return Icon(
Foundation.burst_new,
size: 48,
color: Color(0xff303841),
);
} else if (takenSurvey == true) {
return Icon(
Foundation.check,
size: 48,
color: Color(0xff303841),
);
} else
return Container();
})),
However, I've added in my AdMob adverts using the 'admob_flutter' package, and because setState seems to be constantly running, the advert cannot load - I just see a flashing box. If I remove setState from the code above, the adverts load, but the icons in my app do not update when the value in Cloud Firestore changes.
How do I either exclude my admob_flutter widget from setState, or just use setState (or something else) to only update my FutureBuilder widget? I would like to do so in a way which limits the number of calls on Cloud Firestore, but this is not essential.
I have tried using nested conditional logic but it doesn't seem to work!
Thanks!
What I can suggest you is to use a ValueNotifier, If you want to manipulate simple data like in this case a boolean value, this widget can be perfect. Also you can use a void function instead of a future as follows:
// Add a ValueNotifier for a single value
final ValueNotifier<bool> _takenSurvey = ValueNotifier(null);
void takenSurvey2() async {
final sn = await Firestore.instance
.collection('Controller')
.document('Current Survey')
.get();
surveyName2 = sn['cs'];
final snapShot = await Firestore.instance
.collection('$surveyName2' + '_entrants')
.document(userid)
.get();
if (snapShot.exists) {
// Update the value of the ValueNotifier
_takenSurvey.value = true;
} else {
_takenSurvey.value = false;
}
}
And to listen the changes in that value use a ValueListenableBuilder:
Positioned(
right: 30,
top: 20,
child: ValueListenableBuilder(
valueListenable: _takenSurvey,
builder: (context, takenSurvey, child) {
if(takenSurvey == null){
return Container();
}
else{
if (takenSurvey == false) {
return Icon(
Foundation.burst_new,
size: 48,
color: Color(0xff303841),
);
} else {
return Icon(
Foundation.check,
size: 48,
color: Color(0xff303841),
);
}
}
},
),
)
Hope it helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With