Curso de Flutter con Firebase

BlocBuilder para mostrar datos en Flutter

Curso de Flutter con Firebase

Contenido del curso

BlocBuilder para mostrar datos en Flutter

Resumen

Mostrar datos en tiempo real desde una base de datos en Flutter requiere un manejo cuidadoso de estados. Aquí aprenderás a usar BlocBuilder para renderizar información dinámica en un dashboard de finanzas, controlando estados de carga, éxito, error y datos vacíos sin que tu aplicación se rompa.

Esta guía te sirve si estás construyendo una app con Flutter y BLoC, y quieres calcular balances, ingresos y gastos a partir de transacciones almacenadas en Firestore o cualquier fuente reactiva.

Qué es BlocBuilder y por qué usarlo en Flutter

El widget BlocBuilder escucha de forma constante los cambios de un Bloc y reconstruye la interfaz según el estado actual. Esto te permite manejar con condicionales cada escenario posible sin mezclar lógica de negocio con la UI.

¿Qué hace BlocBuilder en Flutter? Escucha un Bloc y vuelve a construir el widget cada vez que cambia el estado, recibiendo el context y el state como parámetros.

En el caso del dashboard de ingresos y gastos, el BlocBuilder recibe dos tipos genéricos: el bloc IncomeExpenseBloc y el estado IncomeExpenseState. A partir de ahí, dentro del builder se evalúan los estados con una cadena de if y else if [02:14].

Cómo manejar el estado de carga con CupertinoActivityIndicator

El primer condicional verifica si el estado está cargando. Cuando esto ocurre, retornas un widget Center que envuelve un CupertinoActivityIndicator, mostrando al usuario que la información se está procesando.

Este indicador nativo de Cupertino se integra bien en interfaces tipo iOS y evita pantallas en blanco mientras llega la respuesta del backend.

Cómo calcular ingresos y gastos con where y fold en Dart

Cuando el estado pasa a TransactionLoaded, dispones del listado completo de transacciones. Aquí entran en juego dos métodos clave de Dart: where y fold [04:30].

  • where filtra una colección según una condición. En este caso, separa las transacciones por tipo: income o expense.
  • fold recorre la colección filtrada partiendo de un valor inicial y acumula un resultado. Devuelve un double que empieza en 0 y suma los montos uno a uno.
  • La combinación de ambos te da el total acumulado por categoría sin escribir bucles manuales.

El cálculo de totalIncome filtra todas las transacciones cuyo type sea income y suma sus montos. Para totalExpense se repite la misma lógica, pero filtrando por expense.

dart final totalIncome = state.transactions .where((transaction) => transaction.type == TransactionType.income) .fold<double>(0, (sum, transaction) => sum + transaction.amount);

Cómo obtener el balance disponible y la meta del mes

Una vez tienes los totales, calculas el availableBalance restando los gastos a los ingresos. Para mostrar una meta mensual representativa, multiplicas totalIncome por 0.7, asumiendo que el 70 % de tus ingresos es la meta de ahorro o presupuesto del mes.

¿Cómo se calcula el balance disponible? Resta el total de gastos al total de ingresos: availableBalance = totalIncome - totalExpense.

Estos cuatro valores (balance, budget, income, expense) se envían al método buildBody, que se encarga de pintar las cards del dashboard.

Cómo manejar errores y estados vacíos en BlocBuilder

El manejo de estados no termina con éxito y carga. También necesitas cubrir el caso de error y la ausencia de datos para que tu app sea robusta.

  • Si el estado es TransactionError, retornas un Center con un Text que muestra el mensaje del error: "Error loading data ${state.message}".
  • Si ningún condicional se cumple, devuelves un texto por defecto: "No data available". Esto cubre el escenario en que no hay transacciones registradas todavía.
  • Cada rama del condicional retorna un widget distinto, lo que mantiene la UI sincronizada con el estado real del Bloc [09:45].

Esta estructura defensiva evita que tu aplicación falle silenciosamente o muestre pantallas rotas cuando algo sale mal en la consulta a la base de datos.

Cómo pasar variables al widget buildBody en Flutter

Para que buildBody reciba los datos calculados, su firma debe declarar los parámetros con sus tipos. Recibes el BuildContext y cuatro variables double: availableBalance, budget, income y expense.

Dentro del widget, las cards dejan de tener valores quemados y pasan a concatenar las variables usando interpolación de strings. Por ejemplo: "\$${availableBalance.toString()}". El método toString convierte el double en texto plano, evitando que se muestren decimales innecesarios.

Por qué quitar const cuando agregas variables dinámicas

Un detalle importante: cuando un widget contiene valores dinámicos, ya no puede declararse como const. Si tu card usaba const y ahora interpola variables, debes eliminar esa palabra clave. Sin embargo, los widgets que sí permanecen estáticos, como un SizedBox, sí conservan su const para optimizar el renderizado [13:20].

Al guardar los cambios, el dashboard refleja en tiempo real el balance disponible, la meta del mes calculada al 70 %, y dos cards con el desglose de entradas y salidas.

Ahora tienes la base lista. Como reto, intenta implementar el botón "guardar meta" para que el budget deje de ser representativo y se almacene como un valor real en tu base de datos. ¿Cómo lo resolverías tú? Cuéntalo en los comentarios.