Flutter开发中Firebase赋值变量在Scaffold显示初始值问题求助
问题原因
- Firebase的
get()是异步操作,你在build方法中发起请求后,不会等待请求返回就会直接执行后面的return Scaffold逻辑,此时masik还是初始的'minden',所以首次渲染展示的是初始值。 - 你当前用的是
StatelessWidget(无状态组件),本身没有状态更新能力,就算后续异步请求返回给masik赋值成功,也没有机制触发Flutter重新渲染组件,所以UI不会更新。 - 把请求逻辑写在
build方法里是错误的,build方法会因为各种场景频繁触发重绘,会导致重复发起大量无用的Firebase请求。
修正方案
- 把
AddData组件改为StatefulWidget,将masik变量提升为State类的全局成员变量,不要放在build方法中作为局部变量。 - 将Firebase请求逻辑移到
initState生命周期方法中,保证仅在组件初始化时发起一次请求。 - 请求成功拿到结果后,调用
setState方法更新masik的值,触发组件重绘更新UI。
修正后代码如下:
import 'package:flutter/material.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_core/firebase_core.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); runApp(MyApp()); } class MyApp extends StatefulWidget { @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { String masik = ''; @override Widget build(BuildContext context) { return MaterialApp( title: 'Firebase', home: AddData(), ); } } // 改为StatefulWidget class AddData extends StatefulWidget { @override State<AddData> createState() => _AddDataState(); } class _AddDataState extends State<AddData> { String doksi = 'valami más'; var ezlett; // 把masik提升为State类的成员变量 String masik = 'minden'; String sajt = ''; // 可选:增加加载状态优化交互体验 bool isLoading = true; @override void initState() { super.initState(); // 把请求逻辑放在initState中,仅执行一次 FirebaseFirestore.instance .collection('zenek') .doc(doksi) .get() .then((DocumentSnapshot documentSnapshot) { if (documentSnapshot.exists) { String ezegyszoveg = documentSnapshot.data().toString(); print('Document exists on the database $ezegyszoveg'); ezlett = ezegyszoveg.substring(9, ezegyszoveg.indexOf(',')); print(ezlett); // 更新值之后调用setState触发重绘 setState(() { masik = ezegyszoveg.substring(ezegyszoveg.indexOf('text: ')+6, ezegyszoveg.indexOf('}')); isLoading = false; }); print(masik); } }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Colors.green, title: const Text("próba"), ), body:Row( children: [ isLoading ? const CircularProgressIndicator() : Text(masik), ], ) ); } }
补充说明
- 你之前声明的
collectionStream没有用到,如果需要监听集合的实时变化,可以用StreamBuilder组件来监听流数据自动更新UI,不需要手动调用setState。 - 解析文档数据时不要直接转字符串裁切,建议用
documentSnapshot.get('字段名')的方式直接取对应字段的值,稳定性更高。
内容的提问来源于stack exchange,提问作者SuCKEE
相关产品推荐
相关产品推荐

