#flutter #authentication #provider #state-management
#flutter #аутентификация #поставщик #управление состоянием
Вопрос:
Я пришел из HTML / CSS / JQUERY для фона интерфейса, и в основном я был разработчиком серверной части Nodejs. Однако проект, который я взял на себя, был основан на HTML / CSS / jQuery и PHP, и я преуспеваю в этом, пока им не понадобилось мобильное приложение. Поэтому я выбрал flutter, поскольку в тот момент было жарко. Я освоил основы flutter и взял provider в качестве своего государственного управления, а также включил в него логику. Однако у меня есть 2 проблемы, которые я не могу решить.
- Одним из них является сохранение состояния в провайдере, даже когда приложение принудительно закрыто.
- Поддерживайте постоянство входа в систему, если не вышли из системы, и очистите состояние, если вышли из системы.
Для 1. Я не смог найти конкретное решение, кроме хранилища приложений, но тогда мне пришлось бы написать еще много кода, чтобы сохранить в нем все данные и классы.
Для 2. Я выполнил некоторый экспериментальный метод, как показано ниже
runApp(
ChangeNotifierProvider(
create: (_) => UserRepository(), // Here is my auth state provider
child: MyApp(),
),
);
В классе UserRepository пользовательские данные, такие как идентификатор пользователя, хранятся в SharedPreferences, который проверяет, сохранены ли данные пользователя или нет, следовательно, статус становится аутентифицированным или неинициализированным для каждого условия.
Ниже приведен виджет с отслеживанием состояния, который задает статус в отношении UserRepository
class _MyAppState extends State<MyApp> {
ProjectRepository projectRepository = ProjectRepository();
UIKeypadRepository uiKeypadRepository = UIKeypadRepository();
PODRepository podRepository = PODRepository();
Status currentStatus;
//Also there are more Change notifier class here that manages state of various features of the app
void initProviders() {
projectRepository = ProjectRepository();
uiKeypadRepository = UIKeypadRepository();
podRepository = PODRepository();
}
@override
void initState() {
currentStatus = Provider.of<UserRepository>(context, listen: false).status;
//if not logged out current status is authenticated
super.initState();
}
@override
Widget build(BuildContext context) {
return Consumer(builder: (context, UserRepository authStatus, child) {
if (currentStatus != Status.Authenticated) {
initProviders(); // this function is called and all changenotifier classes are reinitialized
}
return MultiProvider(
providers: [
ChangeNotifierProvider.value(value: projectRepository),
ChangeNotifierProvider.value(value: uiKeypadRepository),
ChangeNotifierProvider.value(value: podRepository),
],
//instead of create I used value so if classes are initialized initial values are taken else existing values are made available to below the widget tree
child: MaterialApp(
home: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: LandingPage())),
);
});
}
}
Ответ №1:
Вы можете использовать authStateChanges()
и StreamBuilder для получения статуса аутентификации.
Комментарии:
1. Я не использую firebase? Простой сервер php с mysql.
2. затем вы должны использовать ProxyProvider вместо initProvider(), когда статус аутентификации изменился.
3. Перешел на riverpod, вне контекста провайдера, и жизнь стала намного проще! Спасибо за предложение, я пытался использовать ProxyProvider, но позже заметил, что мне пришлось использовать еще много прокси-провайдеров.