Flutter中如何展示Firebase Get查询获取的数据?
问题分析
data是docRef.get().then()回调里的局部变量,build方法根本访问不到这个变量,所以报错“The getter 'data' isn't defined for the class 'ItemDetails'”。- 构造函数里的异步请求不会等待完成,
build方法会先执行,此时数据还没获取到,就算能访问data也会是空值。 StatelessWidget无法保存状态,数据获取完成后无法触发UI重建展示数据。
解决方案一:使用FutureBuilder(推荐)
FutureBuilder是Flutter专门用来处理异步操作并构建UI的组件,能自动根据异步任务的状态(未完成、成功、失败)渲染对应的UI。
修改后的代码:
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/material.dart'; class ItemDetails extends StatelessWidget { final String itemId; final String docId = "frngqy6aaxb88mw2n09p6e9qhkrkhhmmywrahm8f79e4myuwku6"; ItemDetails(this.itemId, {Key? key}) : super(key: key); // 把获取数据的逻辑封装成Future Future<Map<String, dynamic>?> _getItemData() async { try { final docRef = FirebaseFirestore.instance.collection("collection_name").doc(docId); final DocumentSnapshot doc = await docRef.get(); return doc.data() as Map<String, dynamic>?; } catch (e) { print("Error getting document: $e"); return null; } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Item detail"), ), body: FutureBuilder<Map<String, dynamic>?>( future: _getItemData(), builder: (context, snapshot) { // 异步任务未完成时,显示加载中 if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } // 任务失败或无数据 if (snapshot.hasError || !snapshot.hasData) { return const Center(child: Text("加载失败")); } // 成功获取数据,展示内容 final data = snapshot.data!; return Center(child: Text(data["name"])); }, ), ); } }
解决方案二:改为StatefulWidget保存状态
如果需要在多个方法里访问数据,或者后续要更新数据,可以用StatefulWidget,在initState里发起异步请求,获取数据后更新状态触发UI重建。
修改后的代码:
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/material.dart'; class ItemDetails extends StatefulWidget { final String itemId; const ItemDetails(this.itemId, {Key? key}) : super(key: key); @override State<ItemDetails> createState() => _ItemDetailsState(); } class _ItemDetailsState extends State<ItemDetails> { final String docId = "frngqy6aaxb88mw2n09p6e9qhkrkhhmmywrahm8f79e4myuwku6"; Map<String, dynamic>? _data; bool _isLoading = true; String? _error; @override void initState() { super.initState(); _fetchData(); } void _fetchData() async { try { final docRef = FirebaseFirestore.instance.collection("collection_name").doc(docId); final DocumentSnapshot doc = await docRef.get(); setState(() { _data = doc.data() as Map<String, dynamic>?; _isLoading = false; }); } catch (e) { setState(() { _error = "Error getting document: $e"; _isLoading = false; }); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Item detail"), ), body: _isLoading ? const Center(child: CircularProgressIndicator()) : _error != null ? Center(child: Text(_error!)) : Center(child: Text(_data!["name"])), ); } }
内容的提问来源于stack exchange,提问作者Nibbles
相关产品推荐
相关产品推荐

