Flutter - StreamProvider - 向 Firebase 发送重复出现的 XHR 请求
Posted
技术标签:
【中文标题】Flutter - StreamProvider - 向 Firebase 发送重复出现的 XHR 请求【英文标题】:Flutter - StreamProvider - Sending reoccuring XHR Requests to Firebase 【发布时间】:2020-08-24 16:02:59 【问题描述】:我注意到我的读取请求显着增加,因为我使用StreamProvider 添加了一个新流,我设法通过删除流并且没有重复请求来确认这一点。但我似乎无法追查为什么它会重复。
注意:代码功能正常,只是这些读取请求已经过火了。
串流
//get list of all open enquiries
Stream<List<EnquiryData>> get centreDashboardOpenEnquiries
return centresCollection.document(centreID).collection('enquiries').where('enquiryStatus', whereIn: ['New', 'Contacted', 'Tour Scheduled', 'Tour Completed']).snapshots().map(_enquiryList);
//Map QuerySnapshot to List of EnquiryData
List<EnquiryData> _enquiryList(QuerySnapshot enquiry)
return enquiry.documents.map((doc)
return EnquiryData(
enquiryID: doc.data['enquiryID'].toString(),
parentFirstName: doc.data['firstName'],
parentLastName: doc.data['lastName'],
parentPhoneNumber: doc.data['phoneNumber'],
parentEmail: doc.data['email'],
parentAddress: doc.data['address'],
methodOfEnquiry: doc.data['methodOfEnquiry'],
hearAboutUs: doc.data['hearAboutUs'],
specificHearAboutUs: doc.data['specificHearAboutUs'],
impressionOfCentre: doc.data['firstImpression'],
enquiryStatus: doc.data['enquiryStatus'],
created: doc.data['created'],
lastUpdated: doc.data['lastUpdated'],
);
).toList();
使用 CurrentOpenDataTable 子级调用流
child: StreamProvider<List<EnquiryData>>.value(
value: EnquiryDatabaseService(centreID: widget.centreData.centreID).centreDashboardOpenEnquiries,
child: CurrentOpenDataTable(),
),
CurrentOpenDataTable()
class CurrentOpenDataTable extends StatefulWidget
@override
_CurrentOpenDataTableState createState() => _CurrentOpenDataTableState();
class _CurrentOpenDataTableState extends State<CurrentOpenDataTable>
@override
Widget build(BuildContext context)
final enquiryData = Provider.of<List<EnquiryData>>(context) ?? [];
return DataTable(
showCheckboxColumn: false,
sortColumnIndex: 1,
sortAscending: true,
columns: [
DataColumn(
label: Text('Date'),
),
DataColumn(
label: Text('Name'),
//numeric: true,
),
DataColumn(
label: Text('Status'),
),
],
rows: _enquiryRow(context, enquiryData),
);
_dateFormat(DateTime dateTime)
String formattedDate = DateFormat('dd/MM/yyyy').format(dateTime);
return formattedDate;
_enquiryRow(BuildContext context, List<EnquiryData> enquiryData)
List<DataRow> listOfDataRows = List.generate(
enquiryData.length,
(index) => DataRow(
cells: [
DataCell(Text(_dateFormat(DateTime.fromMillisecondsSinceEpoch(
enquiryData[index].created)))),
DataCell(Text(enquiryData[index].parentFirstName +
' ' +
enquiryData[index].parentLastName)),
DataCell(Text(enquiryData[index].enquiryStatus)),
],
onSelectChanged: (bool selected)
if (selected)
showEnquiryDialog(context, enquiryData[index]);
));
return listOfDataRows;
【问题讨论】:
【参考方案1】:包含StreamProvider
的小部件(我们称之为MyWidget
)不断被重建。
您不应该在StreamProvider<List<EnquiryData>>.value
中创建EnquiryDatabaseService
,而是在initState
中获取流。
例子
class _MyWidgetState extends State<MyWidget>
Stream<List<EnquiryData>> _stream;
@override
initState()
_stream = EnquiryDatabaseService(centreID: widget.centreData.centreID). centreDashboardOpenEnquiries;
// ... in build
StreamProvider.value(
value: _stream,
child: Container(/* ... */),
),
或者不要使用.value
构造函数。
StreamProvider(
create: (_) => EnquiryDatabaseService(centreID: widget.centreData.centreID). centreDashboardOpenEnquiries,
child: Container(/* ... */),
),
阅读更多关于do's and don'ts here 更多参考在这里 - How to deal with unwanted widget build?
【讨论】:
以上是关于Flutter - StreamProvider - 向 Firebase 发送重复出现的 XHR 请求的主要内容,如果未能解决你的问题,请参考以下文章
Flutter:如何处理使用 StreamProvider、FireStore 和使用 Drawer
Flutter Riverpod:使用 StreamProvider 返回 2 个流
Flutter:StreamProvider 的奇怪行为,使用不完整数据重建的小部件
Flutter Provider,当他的参数改变时更新 StreamProvider
如何在 Flutter (Dart) 中通过新路由获取子级 StreamProvider 数据
Flutter:带有 onAuthStateChanged 的 StreamProvider<FirebaseUser> 始终返回 null 作为第一个值