Flutter:如何处理使用 StreamProvider、FireStore 和使用 Drawer
Posted
技术标签:
【中文标题】Flutter:如何处理使用 StreamProvider、FireStore 和使用 Drawer【英文标题】:Flutter: How to handle using StreamProvider, FireStore and using Drawer 【发布时间】:2020-07-24 17:50:43 【问题描述】:我在使用“StreamProvider”和让“Provider.of”交付商品时遇到问题。我有两个相互关联的问题。 (1)我无法让 ProxyProvider 工作(很可能我只是误解了它,它可能不是解决方案)。 (2) 小部件 Drawer()(或我使用它的方式)似乎阻止了“Provider.of”。在树上找不到“StreamProvider”。
在 MyApp() 中我最初有:
return MultiProvider(
providers: [
StreamProvider<User>.value(value: AuthService().user),
StreamProvider<UserData>.value(
value: DatabaseServices(uid: 'user.userUid').userData),
StreamProvider<QuerySnapshot>.value(
value: DatabaseServices(uid: 'user.userUid').allTasks),
StreamProvider<List<TaskDetails>>.value(
value: DatabaseServices(uid: 'user.userUid').userTasksByImportance),
StreamProvider<List<PropertyDetails>>.value(
value: DatabaseServices(uid: 'UuO2DO0JUVbVD0R1JqIclI7fprF3')
.userProperties),
],
child: MaterialApp(
theme: themeData,
home: Wrapper(),
routes:
SettingsForm.id: (context) => SettingsForm(),
TaskList.id: (context) => TaskList(),
AddTask.id: (context) => AddTask(),
EditTask.id: (context) => EditTask(),
PropertyList.id: (context) => PropertyList(),
AddProperty.id: (context) => AddProperty(),
AddUnit.id: (context) => AddUnit(),
TestMarkdown.id: (context) => TestMarkdown(),
,
),
);
我尝试使用 ProxyProvider 将来自 StreamProvider 的 user.userUid 提供给它下面的其他 StreamProvider,但无法正常工作。
接下来在 Wrapper() 我尝试了这个:
class Wrapper extends StatelessWidget
@override
Widget build(BuildContext context)
final user = Provider.of<User>(context);
if (user == null)
return Authenticate();
else
return MultiProvider(
providers: [
StreamProvider<UserData>.value(
value: DatabaseServices(uid: user.userUid).userData),
StreamProvider<List<TaskDetails>>.value(
value: DatabaseServices(uid: user.userUid).userTasksByImportance),
StreamProvider<QuerySnapshot>.value(
value: DatabaseServices(uid: user.userUid).allTasks),
StreamProvider<List<PropertyDetails>>.value(
value: DatabaseServices(uid: user.userUid).userProperties),
],
child: Home(),
);
现在这在 MaterialApp() 之下,我认为这不是一个好主意,但我可以让 user.user.Uid 可用于其他 StreamProvider(s) 并且一切正常。 Home() 和 HomePage() 中的 Provider.of(由 Home() 调用)提供了这些好东西。
现在 Home() 有一个抽屉:
return Scaffold(
drawer: buildDrawer(context),
backgroundColor: Colors.blueAccent[50],
appBar: appBar,
body: Container(
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
decoration: BoxDecoration(
color: Colors.white,
image: DecorationImage(
alignment: Alignment.bottomCenter,
image: AssetImage('assets/property_returns_logo_drawn.png'),
fit: BoxFit.fitWidth),
),
child: HomePage(),
),
);
Drawer buildDrawer(BuildContext context)
final user = Provider.of<User>(context);
final userData = Provider.of<UserData>(context);
final userProperties = Provider.of<List<PropertyDetails>>(context);
final double _minHeight = 40;
final double _maxHeight = 40;
return Drawer(
child: ListView(
padding: EdgeInsets.all(0),
children: <Widget>[
DrawerHeader(
并且 userProperties 在抽屉本身中是可用的,但是从抽屉中调用的任何小部件都会给出错误,即它找不到 Provider.of 的相关 StreamProvider。如果我在 MyAPP() 中返回相关的 StreamProvider,则可以找到相关的 StreamProvider。但是没有来自 Firestore 的值,除非我捏造并且为 user.userUid 硬编码一个有效的 uid:。显然不是一个解决方案,但就 Drawer 调用的小部件而言,它可以工作。
我正在寻找的是了解如何使用 ProxyProvider,或者如果这不是解决方案,如何构建我的代码。也许我可以在从 Drawer 调用的每个小部件中使用 StreamProviders(或 StreamBuilders),但这感觉不对。代码在https://github.com/sctajc/property_returns。
【问题讨论】:
【参考方案1】:截至今天,ProxyProvider 不再作为 StreamProvider 工作,因此您无法按照自己的方式使用它。
要回答为什么您的Drawer
可以访问Provider.of<Foo>
而从它打开的路由却没有,是因为routes
是在您的MaterialApp
中定义的。
这是什么意思?这意味着虽然Drawer
低于Wrapper
,因此可以访问Provider.of<Foo>
,但从技术上讲,其他路由高于Wrapper
小部件。
TL:DR
解决方案就是像这样创建一个ProxyProvider
的DatabaseServices
:
ProxyProvider<User, DatabaseServices>(
update: (_, user, __) => DatabaseServices(uid: user?.userUid),
),
然后,如果您需要利用 UserData,您只需:
Provider.of<DatabaseServices>(context).userData
这样可以避免创建同一个对象 (DatabaseServices) 的 4 个实例,同时可以解决问题。但是,您的应用程序的逻辑需要稍作更改才能使其正常运行,我相信这不会有问题。
我希望这可以帮助你,你可以继续开发你的应用程序!
【讨论】:
谢谢弗朗西斯科。这当然帮助我理解了这个问题,并且我已经按照你的建议进行了代码更改。像 Provider.of以上是关于Flutter:如何处理使用 StreamProvider、FireStore 和使用 Drawer的主要内容,如果未能解决你的问题,请参考以下文章
firebase、flutter应该如何处理好友请求和邀请? [关闭]
我应该如何处理:Wordpress 社交登录(网络)和 Flutter(移动)
Flutter 如何处理 Stream 和 Future 返回错误