【发布时间】:2021-05-19 04:54:16
【问题描述】:
我是 Flutter 的新手,在实现 FireBase 身份验证时对小部件树结构有疑问。
下面是我现在的小部件树。
我使用 Provider 来访问 clind 小部件中的 FirebaseAuthentication 对象,并使用 StreamBuilder 来识别身份验证状态更改。
我的问题是在哪里放置路由。我不确定拥有两个 MaterialApp 是否正确。将路由放在 HomePage 类中感觉不对,而且还会多次重新加载应用程序
部分代码如下。
class LandingPage extends StatelessWidget {
const LandingPage();
@override
Widget build(BuildContext context) {
final firebaseAuth = Provider.of<FirebaseAuth>(context);
final SecureStorage secureStorage = SecureStorage();
void checkAndLoginWithSavedCredentials() {
if (kIsWeb) {
} else if (Platform.isAndroid || Platform.isIOS) {
print(secureStorage.readSecureData('email'));
}
}
return StreamBuilder<User>(
stream: firebaseAuth.authStateChanges(),
builder: (context, AsyncSnapshot<User> snapshot) {
checkAndLoginWithSavedCredentials();
print(snapshot.connectionState.toString());
if (snapshot.connectionState == ConnectionState.active) {
//final bool signedIn = snapshot.hasData;
User user = snapshot.data;
return user == null ? LoginScreen() : HomeScreen();
//return signedIn ? DashBoard() : FirstView();
} else {
return LoginScreen();
}
});
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/home',
routes: {
'/': (context) => LandingPage(),
'/home': (context) => HomeScreen(),
'/notifications': (context) => NotificationList(),
'/fitness': (context) => FitnessScreen(),
'/settings': (context) => SettingsScreen(),
},
debugShowCheckedModeBanner: false,
);
}
}
更新: 根据建议,我将代码更改如下。
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Provider<FirebaseAuth>(
create: (context) => FirebaseAuth.instance,
child: MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => LandingPage(),
'/home': (context) => HomeScreen(),
'/notifications': (context) => NotificationList(),
'/fitness': (context) => FitnessScreen(),
'/settings': (context) => SettingsScreen(),
},
debugShowCheckedModeBanner: false,
),
);
}
}
class LandingPage extends StatelessWidget {
const LandingPage();
@override
Widget build(BuildContext context) {
final firebaseAuth = Provider.of<FirebaseAuth>(context);
}
return StreamBuilder<User>(
stream: firebaseAuth.authStateChanges(),
builder: (context, AsyncSnapshot<User> snapshot) {
print(snapshot.connectionState.toString());
if (snapshot.connectionState == ConnectionState.active) {
User user = snapshot.data;
print(user == null);
if (user == null) {
print('loading Login Screen ...');
return LoginScreen();
} else {
print('loading Home Screen ...');
return HomeScreen();
}
} else {
return LoginScreen();
}
});
}
}
现在应用不会多次重新加载,但是当在小部件树下发生 SignOut 时,它不会更改路由。 LandingPage 确实返回了 LoginPage 小部件,但没有发生路由转换,并且应用程序状态与发生 SignOut 的小部件相同。
我可以在 streamBuilder 中进行强制路由转换,但我认为这不是实现它的方式。
【问题讨论】:
标签: firebase flutter flutter-layout