Почему моя переменная не получает правильное значение от Firestore? - PullRequest
0 голосов
/ 01 августа 2020

Я использую Flutter. Мне нужно получить только одно значение из Firestore и обновить его для всех пользователей. Поэтому я использую listen, чтобы обновлять значение. Я получаю значение в одной переменной, но не могу использовать его вне метода listen.

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"),
    );
  }
}

Некоторые имена на португальском языке, потому что я бразилец, но код по-прежнему понятен. Я новичок в Dart, поэтому, пожалуйста, скажите мне, если я делаю что-нибудь глупое.

1 Ответ

2 голосов
/ 01 августа 2020

function, переданный методу listen, будет выполняться всякий раз, когда значение обновляется, но остальная часть кода выполняется только один раз. Итак, если вы хотите, чтобы Text в контейнере обновлялось каждый раз при обновлении значения - используйте 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");
    ),
  );
}

Итак, в вашем коде listen er добавляется к stream, и сразу же выполняется следующий код, где Container создается с _totalGeradoApp, которое изначально было "0". Каждый раз при обновлении значения _totalGeradoApp обновляется, а текст в Container - нет. При использовании StreamBuilder виджет Text также обновляется всякий раз, когда доступно новое значение.

...