如何在Flutter(Dart)中获得具有新路由的儿童的StreamProvider数据



我正在使用StreamProvider方法用某些数据包装我的小部件,例如Firebase Auth的Auth(在我的应用程序中的任何地方都可以使用(。我想对Firestore值做同样的事情,但它似乎只适用于一个级别。

我有一个数据库调用,一旦完成身份验证检查,它就会查找员工配置文件。当我尝试用Provider.of(context(从我的Home((小部件中获取员工时,效果很好:

这是我的包装小部件(这是我主文件的主页:小部件(

class Wrapper extends StatelessWidget {
@override
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
print(user.uid);
// Return either home or authenticate widget
if (user == null) {
return Authenticate();
}
else {
return StreamProvider<Employee>.value(
value: DatabaseService().linkedEmployee(user.uid),
child: Home(),
);
}
}
}

DatabaseService((中的数据库服务函数:

// Get Linked Employee
Stream<Employee> linkedEmployee(String uid) {
return employeesCollection.where("linkedUser", isEqualTo: uid).snapshots().map(_linkedEmployeeFromSnapShot);
}

Employee _linkedEmployeeFromSnapShot(QuerySnapshot snapshot) {
final doc = snapshot.documents[0];
return Employee(
eId: doc.data["eId"],
employeeCode: doc.data["employeeCode"],
fName: doc.data["fName"],
lName: doc.data["lName"],
docId: doc.documentID
);
}

我可以从树中任何位置的任何小部件访问Provider.of<User>(context)。那么,为什么我不能对Provider.of<Employee>(context)执行同样的操作呢?

当我在除Home((之外的任何小工具中尝试时,我都会得到错误:

错误:无法在此车辆小工具上找到正确的提供商

例如,在我的小部件"车辆:"中

class Vehicles extends StatelessWidget {
@override
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
final employee = Provider.of<Employee>(context);
...

用户提供程序工作正常,我可以打印出来,但员工提供程序不工作。

这与上下文有关吗?谢谢,任何建议都将不胜感激。

我是如何从Home((导航到Vehicles((小部件的,带有一个带有此事件的凸起按钮:

onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Vehicles())
);
},

这里有一个更解释的回复,因此我认为有些人会遇到这个问题,我也认为这有点棘手,尤其是当您的Firestore中有规则要求用户获得访问数据库的授权时。

但通常情况下,您希望围绕MaterialApp()包装提供者(您希望访问所有应用程序(。

所以我会给你看一个简单的例子,让你更容易理解

//The App() handles makes the providers globally accessible
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FirebaseAuthProviderLayer(
child: AuthorizedProviderLayer(
authorizedChild: MatApp(child: StartSwitch()),
unAuthorizedChild: MatApp(child: SignInScreen()),
),
);
}
}
//The MaterialApp Wrapped so that it not has to be rewritten
class MatApp extends StatelessWidget {
Widget child;
MatApp({this.child});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'App',
home: child,
);
}
}
class FirebaseAuthProviderLayer extends StatelessWidget {
final Widget child;
FirebaseAuthProviderLayer({this.child});
@override
Widget build(BuildContext context) {
return StreamProvider<User>.value(
value: FirebaseAuth.instance.authStateChanges(),
child: child,
);
}
}
//And the layer that decides either or not we should attach all the providers that requires the user to be authorized.
class AuthorizedProviderLayer extends StatelessWidget {
Widget authorizedChild;
Widget unAuthorizedChild;
AuthorizedProviderLayer({this.unAuthorizedChild, this.authorizedChild});
User user;
final FirestoreService firestoreService =
FirestoreService(); //The Service made to access Firestore
@override
Widget build(BuildContext context) {
user = Provider.of<User>(context);
if (user is User)
return MultiProvider(
providers: [
StreamProvider<FirestoreUserData>.value(
value: firestoreService.streamUser(),
),
StreamProvider<AppSettings>.value(
value: firestoreService.streamSettings(),
initialData: null,
)
],
child: authorizedChild,
);
return unAuthorizedChild;
}
}

相关内容

  • 没有找到相关文章

最新更新