Reputation: 527
I have a favorite Icon and the number of likes next to it, when I press the button it changes the Icon but it doesn't increment the number, it only increments when I reload the page, how can I change it?
class LanchonetesContact extends StatefulWidget {
final DocumentSnapshot lanchonetes;
LanchonetesContact(this.lanchonetes);
@override
_LanchonetesContactState createState() => _LanchonetesContactState();
}
class _LanchonetesContactState extends State<LanchonetesContact> {
bool liked = false;
void _pressed() {
setState(() {
liked = !liked;
});
}
void _changeLikes() {
setState(() {
if (liked) {
Firestore.instance
.collection('lanchonetes')
.document(widget.lanchonetes.documentID)
.updateData({'likes': FieldValue.increment(1)});
} else {
Firestore.instance
.collection('lanchonetes')
.document(widget.lanchonetes.documentID)
.updateData({'likes': FieldValue.increment(-1)});
}
});
}
@override
Widget Padding(
padding: EdgeInsets.only(top: 0.0),
child: Card(
elevation: 1.0,
child: GestureDetector(
child: Container(
height: 70.0,
width: 390.0,
color: Colors.white,
child: Padding(
padding: EdgeInsets.symmetric(
vertical: 15.0, horizontal: 15.0),
child: Row(
children: <Widget>[
Padding(
padding:
const EdgeInsets.only(left: 100.0, bottom: 30),
child: Icon(
liked ? Icons.favorite : Icons.favorite_border,
color: Colors.black,
size: 50.0,
),
),
Text(
widget.lanchonetes.data["likes"].toString(),
style: TextStyle(fontSize: 40.0),
),
],
),
),
),
onTap: () {
_pressed();
_changeLikes();
},
)),
),
I also notice that it doesn't maintain the state, if I navigate to another page and after return the Icon would not be liked anymore. Any Idea on how to deal with these situations?
Upvotes: 0
Views: 328
Reputation: 1892
Function updateData
is async so setState is updated before the DocumentSnapshot
data is changed. To fix the issue you could do:
void _changeLikes() {
Firestore.instance
.collection('lanchonetes')
.document(widget.lanchonetes.documentID)
.updateData({'likes': FieldValue.increment(liked ? 1 : -1)
.then((_) => setState(() => {}))
}
While this method should work, there is better ways to work with firestore:
Wrap the content with a streambuilder with the snapshot of the document:
StreamBuilder(
stream: Firestore.instance
.collection('lanchonetes')
.document(widget.lanchonetes.documentID).snapshots(),
builder: (context, snapshot) => Text(
snapshot.data.data["likes"].toString(),
style: TextStyle(fontSize: 40.0),
) //DocumentSnapshot is in snapshot.data,
);
and
void _changeLikes() {
Firestore.instance
.collection('lanchonetes')
.document(widget.lanchonetes.documentID)
.updateData({'likes': FieldValue.increment(liked ? 1 : -1);
}
Upvotes: 2