Flutter Firestore 和 StreamBuilder
Posted
技术标签:
【中文标题】Flutter Firestore 和 StreamBuilder【英文标题】:Flutter Firestore and StreamBuilder 【发布时间】:2020-10-01 14:56:17 【问题描述】:我正在尝试为我的颤振应用程序构建一个类似于谷歌新闻源的结构。设计部分没有错误。我尝试了一些虚拟数据并且小部件构建正确。当我尝试将 Firestore 数据转换为小部件时,该小部件将不会构建,并且屏幕上没有任何内容。下面是 StreamBuilder 代码
Widget build(BuildContext context)
height = MediaQuery.of(context).size.height;
width = MediaQuery.of(context).size.width;
return Container(
color: Colors.green[50],
height: height,
width: width,
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(
height: height * 0.04,
),
Container(
height: height * 0.12,
width: width * 0.90,
color: Colors.green[50],
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: EdgeInsets.only(left: width * 0.10),
child: Text('UPCOMING EVENTS',
style: GoogleFonts.tenaliRamakrishna(
textStyle: TextStyle(
fontSize: 30,
fontWeight: FontWeight.w500))),
),
)
],
),
),
StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('Events').snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot)
if (snapshot.hasError)
return Center(child: Text('Error: $snapshot.error'),);
return ListView(
children: snapshot.data.documents
.map<Widget>((DocumentSnapshot document)
return eventCard(
imageUrl: document['ImageUrl'],
title: document['Title'],
description: document['Description'],
venue: document['Venue'],
date: document['Date'],
time: document['Time']);
).toList(),
);
,
)
],
),
));
我的小部件代码是
Widget eventCard(
String imageUrl,
String title,
String description,
String venue,
String date,
String time)
return Padding(
padding: EdgeInsets.all(10),
child: InkWell(
onTap: null,
child: Container(
height: height * 0.50,
width: width * 0.90,
decoration:
kEventsPage.copyWith(borderRadius: BorderRadius.circular(20)),
child: Column(
children: <Widget>[
Expanded(
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20)),
child: Image.network(
imageUrl,
width: width * 90,
fit: BoxFit.fill,
loadingBuilder: (BuildContext context, Widget child,
ImageChunkEvent loadingProgress)
if (loadingProgress == null) return child;
return Align(
alignment: Alignment.bottomRight,
child: LinearProgressIndicator(
backgroundColor: Colors.grey,
value: loadingProgress.expectedTotalBytes != null
? loadingProgress.cumulativeBytesLoaded /
loadingProgress.expectedTotalBytes
: null,
),
);
,
),
),
flex: 6,
),
Expanded(
flex: 4,
child: Padding(
padding: EdgeInsets.only(left: 10),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Flexible(
child: Text(
title,
style: GoogleFonts.roboto(
textStyle: TextStyle(
fontSize: 20, fontWeight: FontWeight.w500)),
),
),
Flexible(
child: Text(
description,
style: GoogleFonts.roboto(
textStyle: TextStyle(
fontSize: 15, fontWeight: FontWeight.w400)),
),
),
Flexible(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Row(
children: <Widget>[
Text(
'Venue: ',
style: GoogleFonts.roboto(
fontWeight: FontWeight.w900),
),
Text(venue)
],
),
Row(
children: <Widget>[
Text(
'Date: ',
style: GoogleFonts.roboto(
fontWeight: FontWeight.w900),
),
Text(date)
],
),
Row(
children: <Widget>[
Text(
'Time: ',
style: GoogleFonts.roboto(
fontWeight: FontWeight.w900),
),
Text(time)
],
)
],
))
],
),
),
)
],
),
),
),
);
错误是
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 9553): The following NoSuchMethodError was thrown building StreamBuilder<QuerySnapshot>(dirty, state:
I/flutter ( 9553): _StreamBuilderBaseState<QuerySnapshot, AsyncSnapshot<QuerySnapshot>>#21f5c):
I/flutter ( 9553): The getter 'documents' was called on null.
I/flutter ( 9553): Receiver: null
I/flutter ( 9553): Tried calling: documents
I/flutter ( 9553):
I/flutter ( 9553): The relevant error-causing widget was:
I/flutter ( 9553): StreamBuilder<QuerySnapshot>
I/flutter ( 9553): file:///D:/Praveen/Flutter/FlutterApps/employee_tracking/lib/screens/Events.dart:169:15
I/flutter ( 9553):
I/flutter ( 9553): When the exception was thrown, this was the stack:
I/flutter ( 9553): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
I/flutter ( 9553): #1 _EventsState.build.<anonymous closure> (package:employeetracking/screens/Events.dart:176:45)
I/flutter ( 9553): #2 StreamBuilder.build (package:flutter/src/widgets/async.dart:509:81)
I/flutter ( 9553): #3 _StreamBuilderBaseState.build (package:flutter/src/widgets/async.dart:127:48)
I/flutter ( 9553): #4 StatefulElement.build (package:flutter/src/widgets/framework.dart:4619:28)
I/flutter ( 9553): #5 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4502:15)
I/flutter ( 9553): #6 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4675:11)
I/flutter ( 9553): #7 Element.rebuild (package:flutter/src/widgets/framework.dart:4218:5)
I/flutter ( 9553): #8 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4481:5)
I/flutter ( 9553): #9 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4666:11)
I/flutter ( 9553): #10 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4476:5)
I/flutter ( 9553): #11 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3446:14)
I/flutter ( 9553): #12 MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:5947:32)
I/flutter ( 9553): ... Normal element mounting (111 frames)
I/flutter ( 9553): #123 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3446:14)
I/flutter ( 9553): #124 Element.updateChild (package:flutter/src/widgets/framework.dart:3211:20)
I/flutter ( 9553): #125 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4527:16)
I/flutter ( 9553): #126 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4675:11)
I/flutter ( 9553): #127 Element.rebuild (package:flutter/src/widgets/framework.dart:4218:5)
I/flutter ( 9553): #128 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2627:33)
I/flutter ( 9553): #129 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:883:20)
I/flutter ( 9553): #130 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:284:5)
I/flutter ( 9553): #131 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1113:15)
I/flutter ( 9553): #132 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1052:9)
I/flutter ( 9553): #133 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:968:5)
I/flutter ( 9553): #137 _invoke (dart:ui/hooks.dart:261:10)
I/flutter ( 9553): #138 _drawFrame (dart:ui/hooks.dart:219:3)
I/flutter ( 9553): (elided 3 frames from dart:async)
I/flutter ( 9553):
I/flutter ( 9553): ════════════════════════════════════════════════════════════════════════════════════════════════════
W/libEGL ( 9553): EGLNativeWindowType 0x78761c2010 disconnect failed
I/SurfaceView( 9553): delay destroy surface control
E/SurfaceView( 9553): surfacePositionLost_uiRtSync mSurfaceControl = null
W/libEGL ( 9553): EGLNativeWindowType 0x78760c5010 disconnect failed
I/flutter ( 9553): Another exception was thrown: Vertical viewport was given unbounded height.
I/flutter ( 9553): Another exception was thrown: RenderBox was not laid out: RenderViewport#48731 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter ( 9553): Another exception was thrown: RenderBox was not laid out: RenderViewport#48731 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter ( 9553): Another exception was thrown: RenderBox was not laid out: RenderIgnorePointer#fd3bc relayoutBoundary=up10 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter ( 9553): Another exception was thrown: RenderBox was not laid out: RenderSemanticsAnnotations#0133e relayoutBoundary=up9 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter ( 9553): Another exception was thrown: RenderBox was not laid out: RenderPointerListener#5ee9f relayoutBoundary=up8 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter ( 9553): Another exception was thrown: RenderBox was not laid out: RenderSemanticsGestureHandler#4cd88 relayoutBoundary=up7 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter ( 9553): Another exception was thrown: RenderBox was not laid out: RenderPointerListener#35642 relayoutBoundary=up6 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter ( 9553): Another exception was thrown: RenderBox was not laid out: _RenderScrollSemantics#54fe5 relayoutBoundary=up5 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter ( 9553): Another exception was thrown: RenderBox was not laid out: RenderRepaintBoundary#15475 relayoutBoundary=up4 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter ( 9553): Another exception was thrown: RenderBox was not laid out: RenderCustomPaint#66748 relayoutBoundary=up3 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter ( 9553): Another exception was thrown: RenderBox was not laid out: RenderRepaintBoundary#01ac9 relayoutBoundary=up2 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter ( 9553): Another exception was thrown: RenderBox was not laid out: RenderRepaintBoundary#01ac9 relayoutBoundary=up2 NEEDS-PAINT
I/flutter ( 9553): Another exception was thrown: RenderBox was not laid out: RenderRepaintBoundary#01ac9 relayoutBoundary=up2 NEEDS-PAINT
W/FlutterJNI( 9553): Tried to send a platform message to Flutter, but FlutterJNI was detached from native C++. Could not send. Channel: lyokone/locationstream. Response ID: 0
W/FlutterJNI( 9553): Tried to send a platform message to Flutter, but FlutterJNI was detached from native C++. Could not send. Channel: lyokone/locationstream. Response ID: 0
【问题讨论】:
【参考方案1】:我找到了原因。这是因为在 Column
小部件中使用了 ListView
。 Column
扩展到主轴方向(垂直轴)的最大尺寸,ListView
也是如此
解决方案:
如果您想让ListView
占用Column
中的整个剩余空间,请使用Flexible
或Expanded
。
Column(
children: <Widget>[
Expanded(
child: ListView(...),
)
],
)
【讨论】:
【参考方案2】:有几件事可以尝试。
1) 替换
if (snapshot.hasError)
return Center(child: Text('Error: $snapshot.error'),);
与:
if (snapshot.hasError)
return Center(child: Text('Error: $snapshot.error'),);
if (!snapshot.hasData)
return Center(child: Text('No data'),);
这将使构建器有时间获取数据。
2) 如果您看到 No data
,则转到 Firebase 控制台 > 数据库 > firestore 并检查数据库根目录中是否有一个名为 Events
的集合。检查大小写,检查是否有多余的不可见空格。
如果存在,点击查看里面是否有数据
【讨论】:
是的,现在试过了,但屏幕上除了“即将发生的事件”之外什么都没有 数据在那里,如果我在 StreamBuilder 的 builder 方法中打印数据,它会在终端中打印数据。以上是关于Flutter Firestore 和 StreamBuilder的主要内容,如果未能解决你的问题,请参考以下文章
Flutter Geofire 和 Firestore 读取问题
Firestore 为 noSQL 和 Flutter 复制 SQL 连接
Flutter:Firebase 身份验证和 Firestore 快照流
Flutter 和 Firestore 基于位置的查询和数据结构