rafael__bg
rafael__bg

Reputation: 61

Why is my variable not receiving the right value from Firestore?

I'm using Flutter. I need to get just one value from Firestore and update it for all users. So I use a listen to keep the value updated. I receive the value in one variable but I can't use it outside the listen method.

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
 
class PaginaGraficos extends StatefulWidget {
  @override
  _PaginaGraficosState createState() => _PaginaGraficosState();
}
 
class _PaginaGraficosState extends State<PaginaGraficos> {
  
  @override
  Widget build(BuildContext context) {
 
    String _totalGeradoApp = "0";
 
    _getTotalGeradoApp () {
      Firestore.instance.collection("dados_app").snapshots().listen(
              ( snapshot ){
            var totalGeradoApp;
            for( DocumentSnapshot item in snapshot.documents ){
              var dados = item.data;
              totalGeradoApp = dados["total_gerado_app"];
              print("totalGeradoApp: $totalGeradoApp");
            }
            _totalGeradoApp = totalGeradoApp;
          }
      );
    }
    
    _getTotalGeradoApp();
    print("_totalGeradoApp: $_totalGeradoApp");
 
    return Container(
      child: Text("$_totalGeradoApp"),
    );
  }
}

Some names are in Portuguese because I'm Brasilian but the code is still understandable. I'm new with Dart so please tell me if I'm doing something stupid.

Upvotes: 0

Views: 48

Answers (1)

Navaneeth P
Navaneeth P

Reputation: 1561

The function passed to the listen method will execute whenever the value is updated, but the rest of the code runs only once. So, if you want the the Text in the container to be updated whenever the value is updated - use a StreamBuilder.

@override
Widget build(BuildContext context) {
  return Container(
    child: StreamBuilder(
      stream: Firestore.instance.collection("dados_app").snapshots(),
      builder: (context, snapshot) {
        
        if(!snapshot.hasData) {
          return Text('Loading...');
        }

        // update _totalGeradoApp
        var totalGeradoApp;
        var docs = (snapshot.data as QuerySnapshot).documents;
        for(var item in docs) {
          var dados = item.data;
          totalGeradoApp = dados["total_gerado_app"];
        }
        _totalGeradoApp = totalGeradoApp;

        // return Text Widget with updated text
        return Text("$_totalGeradoApp");
    ),
  );
}

So, in your code the listener is added to the stream and immediately the next code is executed where a Container is created with _totalGeradoApp, which was "0" initially. Whenever the value was updated _totalGeradoApp is updated but the text in the Container is not. By using a StreamBuilder the Text widget is also updated whenever a new value is available.

Upvotes: 2

Related Questions