Art*_*xha 6 firebase firebase-authentication flutter-web flutter-provider
我正在使用来自 Firebase 的 authStateChanges 流和 flutter。我有两种视图,一种用于移动设备,另一种用于 Web 应用程序。如果用户未连接、登录或通过身份验证,我想将用户重定向到登录屏幕。起初它运行良好,但当我登录并刷新浏览器时,我加载登录屏幕大约 1 秒,然后再次出现 Web 屏幕。我用 print 检查了发生的情况,从我所看到的情况来看,authStateChanges Stream 在 1-2 秒内为空(当登录屏幕出现时),然后当流接收到连接的用户时有一个值。有没有办法检查或等到身份验证完成后再加载登录屏幕(当它不能加载它时)?
我的主要组件包含 StreamBuilder 如下:
Widget build(BuildContext context) {
final firebaseAuthService = Provider.of<FirebaseAuthService>(context);
return StreamBuilder<User>(
stream: firebaseAuthService.authStateChanges(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
User user = snapshot.data;
if (user == null) {
//first time no connection
return SignIn();
}
if (kIsWeb) {
return WebMain(user: user);
}
// load mobile version
return MobileMain();
}
return Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
});
}
Run Code Online (Sandbox Code Playgroud)
在这里您可以找到我的 FirebaseAuth 包装类,其中包含来自 firebase 的方法:
class FirebaseAuthService {
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
User _user;
bool get isAuthenticated {
return _user == null ? false : true;
}
User get user {
return _user;
}
Future<User> signInWithEmailAndPassword(
String userEmail, String userPassword) async {
return _user = await _firebaseAuth
.signInWithEmailAndPassword(email: userEmail, password: userPassword)
.then((userCredential) => userCredential.user);
}
Stream<User> authStateChanges() {
_user = _firebaseAuth.currentUser;
return _firebaseAuth.authStateChanges();
}
Future<void> signOut() async {
return _firebaseAuth.signOut();
}
}
Run Code Online (Sandbox Code Playgroud)
虽然我不确定为什么 authStateChanges 在用户登录状态更改时(通常是一秒钟后)不通知,但类似的功能似乎确实适合您的用例。
尝试 idTokenChanges()
FirebaseAuth.instance.idTokenChanges().listen((event) {
print("On Data: ${event}");
});
Run Code Online (Sandbox Code Playgroud)
此事件将返回您的 Firebase User 对象。刷新时,它最初可能返回“null”,但在一秒钟内,返回您登录的用户。您可以让登录页面等待几秒钟,以确保登录的用户没有被初始化。
编辑:虽然可能有更好的解决方案,但这目前对我有用。
final subscription = FirebaseAuth.instance.idTokenChanges().listen(null);
subscription.onData((event) async {
if(event != null) {
print("We have a user now");
isLoading = false;
print(FirebaseAuth.instance.currentUser);
subscription.cancel();
Navigator.push(
context,
MaterialPageRoute(builder: (context) => OverviewController())
);
} else {
print("No user yet..");
await Future.delayed(Duration(seconds: 2));
if(isLoading) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => LoginController())
);
isLoading = false;
subscription.cancel();
}
}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3572 次 |
| 最近记录: |