flutter - Flutter & Provider 自动登录
问题描述
所以我正在尝试使用 Provider 和 Consumer 设置自动登录,但我遇到的问题是页面没有更新。我猜是因为它传递了相同的小部件,所以它没有改变它,但我不知道如何修复它......
更新:
因此,当我登录或注销时,即使控制台显示正在调用消费者的登录,它仍保留在同一页面上,我认为如果用户登录或未登录,它在应用程序的初始启动中唯一一次可以使用
代码:
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
List<CameraDescription> cameras = await availableCameras();
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider<ThemeProvider>(
create: (_) => ThemeProvider(Themes.light),
),
ChangeNotifierProvider<CameraProvider>(
create: (_) => CameraProvider(cameras),
),
ChangeNotifierProvider<NetworkProvider>(
create: (_) => NetworkProvider.instance(),
),
ChangeNotifierProvider<UserProvider>(
create: (_) => UserProvider.instance(),
),
],
child: DevicePreview(
builder: (context) => App(
page: Consumer4<ThemeProvider, CameraProvider, NetworkProvider, UserProvider>(
builder: (context, theme, camera, network, user, child) {
Funcs.logger('Consumer: ${user.status}');
return user.status == UserStatus.Null
? LoadingPage(text: 'Loading...')
: user.status == UserStatus.Unauthenticated
? WelcomePage()
: user.status == UserStatus.Authenticated
? user.user.isEmployer ? EmployerPage() : SeekerPage()
: LoadingPage(text: 'Loading...');
},
),
),
enabled: (await Funcs.isPhysicalDevice()),
),
),
);
}
class App extends StatelessWidget {
final Widget page;
const App({Key key, this.page}) : super(key: key);
@override
Widget build(BuildContext context) => Platform.isIOS
? CupertinoApp(
home: this.page,
theme: Utils.currentTheme(context: context).cupertinoOverrideTheme,
navigatorObservers: [
Services().analytics.firebaseAnalyticsObserver,
],
title: Constants.title,
localizationsDelegates: const <LocalizationsDelegate<dynamic>>[
DefaultMaterialLocalizations.delegate,
DefaultWidgetsLocalizations.delegate,
],
debugShowCheckedModeBanner: false,
)
: MaterialApp(
home: this.page,
theme: Utils.currentTheme(context: context),
navigatorObservers: [
Services().analytics.firebaseAnalyticsObserver,
],
title: Constants.title,
localizationsDelegates: const <LocalizationsDelegate<dynamic>>[
DefaultMaterialLocalizations.delegate,
DefaultWidgetsLocalizations.delegate,
],
debugShowCheckedModeBanner: false,
);
}
user_provider.dart
enum UserStatus { Null, Authenticated, Authenticating, Unauthenticated, Unauthenticating }
class UserProvider with ChangeNotifier {
var _auth;
User _user;
UserStatus _status = UserStatus.Null;
UserProvider.instance() : _auth = Services().auth.auth {
_auth.onAuthStateChanged.listen(
(u) async {
if (u != null) {
if (await APIs().users.userExists(userID: u.uid))
Funcs.logger('if');
await APIs().users.user(userID: u.uid).then((user) {
this.user = user;
this.status = UserStatus.Authenticated;
return null;
});
} else {
Funcs.logger('else');
this.user = null;
this.status = UserStatus.Unauthenticated;
}
notifyListeners();
},
);
}
get auth => this._auth;
User get user => this._user;
UserStatus get status => _status;
set user(User value) {
this._user = value;
notifyListeners();
}
set status(UserStatus value) {
_status = value;
notifyListeners();
}
Future verify({
String phoneNumber,
int forceResendingToken,
Future<Function> verificationCompleted(AuthCredential ac),
Future<Function> onCodeAutoRetrievalTimeout(String vID),
Future<Function> onCodeSent(String vID, int code),
Function verificationFailed(e),
}) async {
try {
await Services().auth.verifyPhoneNumber(
phoneNumber: phoneNumber,
forceResendingToken: forceResendingToken,
verificationCompleted: (ac) async => await verificationCompleted(ac),
onCodeAutoRetrievalTimeout: (vID) async => await onCodeAutoRetrievalTimeout(vID),
onCodeSent: (vID, code) async => await onCodeSent(vID, code),
verificationFailed: verificationFailed);
} catch (e) {
return null;
}
}
Future<String> loginWithPhone({String vID, String smsCode}) async {
try {
this.status = UserStatus.Authenticating;
notifyListeners();
return (await Services().auth.loginWithPhone(
vID: vID,
smsCode: smsCode,
onFailure: (e) => Funcs.logger(e),
))
.user
.uid;
} catch (e) {
this.status = UserStatus.Unauthenticated;
notifyListeners();
return null;
}
}
Future<String> loginWithAuthCredential({AuthCredential ac}) async {
try {
this.status = UserStatus.Authenticating;
notifyListeners();
return (await Services().auth.loginWithAuthCredential(
ac: ac,
onFailure: (e) => Funcs.logger(e),
))
.user
.uid;
} catch (e) {
this.status = UserStatus.Unauthenticated;
notifyListeners();
return null;
}
}
Future logout() async {
this.status = UserStatus.Unauthenticating;
notifyListeners();
await Services().auth.logout();
this.status = UserStatus.Unauthenticated;
notifyListeners();
return Future.delayed(Duration.zero);
}
}
Performing hot restart...
Syncing files to device sdk gphone x86...
Restarted application in 3,417ms.
I/flutter ( 6497): ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter ( 6497): │ #0 Funcs.logger (package:shaqay/frontend/configs/funcs.dart:200:38)
I/flutter ( 6497): │ #1 main.().() (package:shaqay/main.dart:37:21)
I/flutter ( 6497): ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
I/flutter ( 6497): │ Consumer: UserStatus.Null
I/flutter ( 6497): └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
W/FA ( 6497): setCurrentScreen cannot be called with the same class and name
I/flutter ( 6497): ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter ( 6497): │ #0 Funcs.logger (package:shaqay/frontend/configs/funcs.dart:200:38)
I/flutter ( 6497): │ #1 new UserProvider.instance.() (package:shaqay/backend/providers/user_provider.dart:25:17)
I/flutter ( 6497): ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
I/flutter ( 6497): │ else
I/flutter ( 6497): └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter ( 6497): ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter ( 6497): │ #0 Funcs.logger (package:shaqay/frontend/configs/funcs.dart:200:38)
I/flutter ( 6497): │ #1 main.().() (package:shaqay/main.dart:37:21)
I/flutter ( 6497): ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
I/flutter ( 6497): │ Consumer: UserStatus.Unauthenticated
I/flutter ( 6497): └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter ( 6497): ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter ( 6497): │ #0 Funcs.logger (package:shaqay/frontend/configs/funcs.dart:200:38)
I/flutter ( 6497): │ #1 main.().() (package:shaqay/main.dart:37:21)
I/flutter ( 6497): ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
I/flutter ( 6497): │ Consumer: UserStatus.Unauthenticated
I/flutter ( 6497): └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter ( 6497): ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter ( 6497): │ #0 Funcs.logger (package:shaqay/frontend/configs/funcs.dart:200:38)
I/flutter ( 6497): │ #1 main.().() (package:shaqay/main.dart:37:21)
I/flutter ( 6497): ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
I/flutter ( 6497): │ Consumer: UserStatus.Unauthenticated
I/flutter ( 6497): └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/BiChannelGoogleApi( 6497): [FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzaq@160e295
I/flutter ( 6497): ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter ( 6497): │ #0 Funcs.logger (package:shaqay/frontend/configs/funcs.dart:200:38)
I/flutter ( 6497): │ #1 _LoginPageState._mobile.().() (package:shaqay/frontend/pages/auth/login_page.dart:123:35)
I/flutter ( 6497): ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
I/flutter ( 6497): │ CODE SENT
I/flutter ( 6497): └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter ( 6497): IF YOU WANT TO USE COLOR FILL FOR EACH CELL THEN SET enableActiveFill = true
I/BiChannelGoogleApi( 6497): [FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzaq@160e295
I/flutter ( 6497): ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter ( 6497): │ #0 Funcs.logger (package:shaqay/frontend/configs/funcs.dart:200:38)
I/flutter ( 6497): │ #1 main.().() (package:shaqay/main.dart:37:21)
I/flutter ( 6497): ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
I/flutter ( 6497): │ Consumer: UserStatus.Authenticating
I/flutter ( 6497): └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
D/FirebaseAuth( 6497): Notifying id token listeners about user ( uDjugkETzsTWbQZIDf7XFxenE7v1 ).
D/FirebaseAuth( 6497): Notifying auth state listeners about user ( uDjugkETzsTWbQZIDf7XFxenE7v1 ).
I/flutter ( 6497): ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter ( 6497): │ #0 Funcs.logger (package:shaqay/frontend/configs/funcs.dart:200:38)
I/flutter ( 6497): │ #1 new UserProvider.instance.() (package:shaqay/backend/providers/user_provider.dart:18:19)
I/flutter ( 6497): ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
I/flutter ( 6497): │ if
I/flutter ( 6497): └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter ( 6497): ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter ( 6497): │ #0 Funcs.logger (package:shaqay/frontend/configs/funcs.dart:200:38)
I/flutter ( 6497): │ #1 main.().() (package:shaqay/main.dart:37:21)
I/flutter ( 6497): ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
I/flutter ( 6497): │ Consumer: UserStatus.Authenticated
I/flutter ( 6497): └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
解决方案
NotificationListener
我会发布我的设置,也许它会帮助你MaterialApp
说实话,你的设置与我的主要区别非常相似您的设置更高一级,我认为您无法将其包裹起来App
。
Consumer<Auth>(
builder: (_, auth, __) => NotificationListener(
child: MaterialApp(
theme: ThemeData(bottomAppBarTheme: BottomAppBarTheme()),
home: FutureBuilder(
future:
Future.wait([auth.isEmailVerified(), auth.tryAutoLogin()]),
builder: (BuildContext ctx, AsyncSnapshot authResultSnapshot) =>
authResultSnapshot.connectionState == ConnectionState.done
? authResultSnapshot.data[1]
? authResultSnapshot.data[0]
? Example()
: EmailVerification()
: LoginScreen()
: SplashScreen(),
),
推荐阅读
- perl - 如何抽象多个嵌套循环?
- sql-server - 您的应用程序错误中发生了未处理的异常
- android - 切换到 PreferenceFragmentCompat 后没有分隔符
- html - Bootstrap 4页脚到底部高度
- tsql - 使用 AND 的 SQL Where 子句
- java - 如何从 IntelliJ 插件的操作事件创建文件?
- c++11 - 从 .txt 文件中读取并循环直到换行
- spring - Spring Boot 2 OAuth2 资源服务器不访问授权服务器进行访问令牌验证
- html - 如何在 CSS 和 HTML 上排列文本的顺序
- android - 安装两个版本的 apk(具有不同的 applicationId)