У меня проблема с использованием 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 для предоставления user.userUid из StreamProvider в другие StreamProviders ниже этого, но не могли заставить что-либо работать.
Далее в 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 (ов), и все работает. Provider.of в Home () и HomePage () (вызываемые Home ()) предоставили вкусности.
Теперь у Home () есть Drawer:
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 доступен внутри самого ящика, но любой виджет, вызываемый из ящика, выдает ошибку, что он не может найти соответствующий StreamProvider для провайдера. Если я опровергаю соответствующий StreamProvider обратно в MyAPP (), соответствующий StreamProvider может быть найден. Но без значений из Firestore, если я не выдумал и для user.userUid жестко закодировал действительный uid :. Очевидно, что это не решение, но оно работает в отношении виджетов, вызываемых Drawer.
Я ищу, чтобы понять, как использовать ProxyProvider или, если это не решение, как структурировать мой код. Может быть, я могу использовать StreamProviders (или StreamBuilders) в каждом виджете, вызываемом из Drawer, но это не так. Код: https://github.com/sctajc/property_returns.