Flutter 在使用 StreamBuilder 从 firebase 加载数据之前显示红色错误屏幕,如何解决?
Posted
技术标签:
【中文标题】Flutter 在使用 StreamBuilder 从 firebase 加载数据之前显示红色错误屏幕,如何解决?【英文标题】:Flutter show's a red error screen before loading data from firebase using StreamBuilder, how to fix? 【发布时间】:2020-02-11 06:33:10 【问题描述】:我正在从 firebase 获取数据并使用该数据制作卡片。显示用户的某些数据 从数据库中,数据加载正常,但 1 秒或更长时间出现红色错误屏幕。我希望这个消失我会告诉你我的代码。有人可以帮我看看出了什么问题。我不知道发生这种情况我做错了什么,我得到了错误
在 null 上调用了 getter 'uid'。 接收方:空 尝试调用:uid
在 null 上调用了方法“[]”。 接收方:空 尝试调用:
这是我的代码,任何帮助将不胜感激,谢谢
class CardBuilder extends StatefulWidget
final String title;
final String text;
final IconData icon;
CardBuilder(Key key, this.title,this.text,this.icon): super(key: key);
@override
_CardBuilderState createState() => _CardBuilderState();
class _CardBuilderState extends State<CardBuilder>
FirebaseUser user;
String error;
void setUser(FirebaseUser user)
setState(()
this.user = user;
this.error = null;
);
void setError(e)
setState(()
this.user = null;
this.error = e.toString();
);
@override
void initState()
super.initState();
FirebaseAuth.instance.currentUser().then(setUser).catchError(setError);
@override
Widget build(BuildContext context)
return StreamBuilder(
stream: Firestore.instance.collection(UserInformation).document(user.uid).snapshots(),
builder: (context, snapshot)
var userDocument = snapshot.data;
// User userDocument here ..........
return Card(
margin: EdgeInsets.only(left: 20,right: 20,top: 20),
child: ListTile(
leading:
Icon(widget.icon, color: QamaiGreen, size: 20.0),
title: AutoSizeText(
'$widget.title : $userDocument[widget.text]',
style: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.w600,
color: QamaiThemeColor,
fontSize: 15
),
maxLines: 1,
maxFontSize: 15,
minFontSize: 12,
),
));
);
【问题讨论】:
【参考方案1】:所以在尝试了一些东西之后,我终于修复了这个错误。决定发布答案,因为这个问题在网上没有任何解决方案。至少我找不到一个。希望这可以帮助遇到同样问题的人
我首先做的是声明一个包含 user.uid 值的字符串
String userid;
void _getUser() async
FirebaseUser user = await FirebaseAuth.instance.currentUser();
userid=user.uid;
现在在卡片生成器小部件中,我摆脱了额外的东西,并在初始化状态下简单地调用了 _getUser() 方法
class _CardBuilderState extends State<CardBuilder>
@override
void initState()
super.initState();
_getUser();
@override
Widget build(BuildContext context)
return StreamBuilder(
stream: Firestore.instance.collection(UserInformation).document(userid).snapshots(),
builder: (context, snapshot)
if(snapshot.hasData)
final userDocument = snapshot.data;
final title=userDocument[widget.text];
return Card(
margin: EdgeInsets.only(left: 20,right: 20,top: 20),
child: ListTile(
leading:
Icon(widget.icon, color: QamaiGreen, size: 20.0),
title: AutoSizeText(
'$widget.title : $title',
style: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.w600,
color: QamaiThemeColor,
fontSize: 15
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
maxFontSize: 15,
minFontSize: 9,
),
));
else
return Card(
margin: EdgeInsets.only(left: 20,right: 20,top: 20),
child: ListTile(
leading:
Icon(widget.icon, color: QamaiGreen, size: 20.0),
title: AutoSizeText(
'LOADING...',
style: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.w600,
color: QamaiThemeColor,
fontSize: 15
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
maxFontSize: 15,
minFontSize: 9,
),
));
);
最后的更改是添加一个条件检查快照是否有数据。在我的情况下,将特定文档字段保存在最终变量中也有很大帮助
final title=userDocument[widget.text];
最后添加了一个 else 条件来模拟显示加载文本的相同卡片界面。如果你愿意,你可以使用 CirculorIndicator,这也对我有用,这对界面来说看起来更自然。
【讨论】:
【参考方案2】:您可以在加载数据时显示进度指示器 如下图
return StreamBuilder(
stream: Firestore.instance.collection(UserInformation).document(user.uid).snapshots(),
builder: (context, snapshot)
//==========show progress============
if (!snapshot.hasData)
return CircularProgressIndicator()
var userDocument = snapshot.data;
// User userDocument here ..........
【讨论】:
感谢您的回复,这根本不起作用。对红屏影响为零 Fork 你的问题,你可以加载数据,但是在加载数据之前你会得到一个红屏,你可以使用流构建器初始数据的属性 设置初始数据 虽然我的回答对我来说效果很好 我不知道在初始数据中设置什么,您有什么建议吗?【参考方案3】:在 main.dart 中试试这个:
void main() async
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
【讨论】:
以上是关于Flutter 在使用 StreamBuilder 从 firebase 加载数据之前显示红色错误屏幕,如何解决?的主要内容,如果未能解决你的问题,请参考以下文章
FirebaseStorage + Flutter,streamBuilder?
在 Flutter 中使用 streamBuilder 时条件不起作用
如何在 Flutter Web 上使用 StreamBuilder 和 Firestore?
Flutter:Streambuilder 导致 Firestore 上的读取过多
Flutter Refreshindicator 在使用 StreamBuilder 添加新项目后重建 Listview.Builder