以前有人使用Streambuilder和Flutter和GoRouter来保持用户状态吗?
目前,我正在使用默认的颤振导航,它运行良好(参见下面),但我现在正尝试用GoRouter替换
我以前使用默认颤振导航的导航设置
home: StreamBuilder(
stream: AuthMethods().authChanges,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
}
if (snapshot.hasData) {
return const TabsScreen();
}
return const AuthScreen();
}),
);
}我现在的goRouter代码。我想知道在哪里可以使用以下d代码中的Streambuilder来持久化我的应用程序的用户状态(或者Streambuilder是否可以与go路由器一起使用)
GoRouter routeConstruct() {
return GoRouter(
routes: <RouteBase>[
GoRoute(
path: '/',
builder: (BuildContext context, GoRouterState state) {
return const PublicScreen();
},
routes: <RouteBase>[
GoRoute(
path: Events_Screen,
builder: (BuildContext context, GoRouterState state) {
return const EventsScreen();
},
),
GoRoute(
path: "$EventDetail_Screen/:eventId",
builder: (BuildContext context, GoRouterState state) {
return EventDetailScreen(eventId: state.params['eventId']!);
},
),
...
]),
],
);我能否使用Streambuilder和GoRouter来持久化用户身份验证状态?如果可以,在goRouter代码中,我可以在哪里使用Streambuilder来根据Auth状态确定要显示哪个小部件?谢谢
###########################
类AuthMethods
class AuthMethods {
final FirebaseAuth _auth = FirebaseAuth.instance;
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
Stream<User?> get authChanges => _auth.authStateChanges();
// --> use of bang ! operator here
User get user => _auth.currentUser!;
Future<bool> signInWithGoogle(BuildContext context) async {
bool res = false;
try {
final GoogleSignInAccount? googleUser = await GoogleSignIn().signIn();
final GoogleSignInAuthentication? googleAuth =
await googleUser?.authentication;
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth?.accessToken, idToken: googleAuth?.idToken);
UserCredential userCredential =
await _auth.signInWithCredential(credential);
User? user = userCredential.user;
if (user != null) {
if (userCredential.additionalUserInfo!.isNewUser) {
await _firestore.collection('users').doc(user.uid).set({
'username': user.displayName,
'uid': user.uid,
'profilePhoto': user.photoURL,
});
}
res = true;
}
} on FirebaseAuthException catch (e) {
showSnackBar(context, e.message!);
res = false;
}
return res;
}类RouteNotifier
class RouterNotifier extends ChangeNotifier {
RouterNotifier(this._authMethods) {
_authMethods.authChanges.listen((event) {
notifyListeners();
});
}
final AuthMethods _authMethods;
String? redirect(BuildContext context, GoRouterState state) {
final onLoginPage = state.location == '/$AuthScreen';
final onHomePage = state.location == '/$Tabs_Screen';
// --> The getter 'isEmpty' isn't defined for the type 'User'.
// --> User get user => _auth.currentUser!; used a bang operator
if (_authMethods.user.isEmpty && onHomePage) {
return '/$AuthScreen';
}
// --> The getter 'isEmpty' isn't defined for the type 'User'.
if (_authMethods.currentUser.isNotEmpty && onLoginPage) {
return '/$Tabs_Screen';
}
return null;
}
}router.dart
GoRouter routeConstruct() {
return GoRouter(
refreshListenable: router,
routes: <RouteBase>[
GoRoute(
path: '/',
builder: (BuildContext context, GoRouterState state) {
return const PublicScreen();
},
routes: <RouteBase>[
GoRoute(
path: Events_Screen,
builder: (BuildContext context, GoRouterState state) {
return const EventsScreen();
},
),
GoRoute(
path: "$EventDetail_Screen/:eventId",
builder: (BuildContext context, GoRouterState state) {
return EventDetailScreen(eventId: state.params['eventId']!);
},
),
]),
],
);
}发布于 2022-11-18 11:38:02
在go路由器5.0.0之前:
go路由器有一个名为GoRouterRefreshStream的类,所以在go路由器中
GoRouter (
....
refreshListenable: GoRouterRefreshStream(AuthMethods().authChanges),但是在go路由器5.0.0之后,它们是移除的
因此,您必须创建自己的通知程序:
class RouterNotifier extends ChangeNotifier {
RouterNotifier(this._authMethods) {
_authMethods.authChanges.listen((event) {
notifyListeners();
});
}
final AuthMethods _authMethods;
}围棋路由器:
GoRouter(
debugLogDiagnostics: false,
....
...
refreshListenable: RouterNotifier(AuthMethods()),
...
);go路由器如何像以前使用的流生成器那样工作呢?
重定向派上用场:
final router = RouterNotifier(AuthMethods());
GoRouter (
...
refreshListenable: router,
redirect: router.redirect,在RouterNotifier类中:
class RouterNotifier extends ChangeNotifier {
RouterNotifier(this._authMethods) {
_authMethods.authChanges.listen((event) {
notifyListeners();
});
}
final AuthMethods _authMethods;
String? redirect(BuildContext context, GoRouterState state) {
final onLoginPage = state.location == '/login';
final onHomePage = state.location == '/';
if (_authMethods.currentUser.isEmpty && onHomePage) {
return '/login';
}
if (_authMethods.currentUser.isNotEmpty && onLoginPage) {
return '/';
}
return null;
}}
类用户模型:
class User {
String id;
.........
some variable i need from db;
static const empty = User(id: '');
bool get isEmpty => this == User.empty;
bool get isNotEmpty => this != User.empty;
}在溪流上:
Stream<User> get user {
// map the user if user null is mean empty
return _firebaseAuth.authStateChanges().asyncMap((fUser) async {
if (fUser == null) {
const User user = User.empty;
return user;
} else {
// in my case i need to take some data from Firestore
....
await datafromDb() // if you dont need to wait future, remove async map, just use normal map
return fUser.withBiodata();https://stackoverflow.com/questions/74486264
复制相似问题