Я новичок в мире флаттера и разработки мобильных приложений и борюсь с тем, как передавать пользовательские данные в моем приложении.
Я пробовал несколько вещей, но ни один из них не кажется отличным, и я уверен, что есть лучшие образцы практики, которым я должен следовать.
Поскольку это упрощает примеры, я использую firebase для аутентификации. В настоящее время у меня есть отдельный маршрут для входа в систему. После входа в систему мне нужна модель User в большинстве представлений для проверки разрешений на то, что показывать, отображения информации о пользователе в ящике и т. Д.
У Firebase есть await firebaseAuth.currentUser();
. Лучше ли вызывать это везде, где вам может понадобиться пользователь? и если да, то где лучше всего сделать этот звонок?
flutter codelab показывает отличный пример аутентификации пользователей перед разрешением записи. Однако, если странице необходимо проверить аутентификацию, чтобы определить, что строить, асинхронный вызов не может перейти в метод build
.
initState
Один из методов, который я пробовал, - переопределить initState и запустить вызов, чтобы получить пользователя. Когда будущее завершится, я вызываю setState
и обновляю пользователя.
FirebaseUser user;
@override
void initState() {
super.initState();
_getUserDetail();
}
Future<Null> _getUserDetail() async {
User currentUser = await firebaseAuth.currentUser();
setState(() => user = currentUser);
}
Это работает прилично, но похоже на церемонию для каждого виджета, который в этом нуждается. Также есть вспышка, когда экран загружается без пользователя, а затем обновляется вместе с пользователем после завершения в будущем.
Пропустить пользователя через конструктор
Это тоже работает, но представляет собой множество шаблонов для передачи пользователю всех маршрутов, представлений и состояний, которым может потребоваться доступ к ним. Кроме того, мы не можем просто делать popAndPushNamed
при переходе маршрутов, потому что мы не можем передать ему переменную. Нам нужно изменить маршруты примерно так:
Navigator.push(context, new MaterialPageRoute(
builder: (BuildContext context) => new MyPage(user),
));
Унаследованные виджеты
https://medium.com/@mehmetf_71205/inheriting-widgets-b7ac56dbbeb1
В этой статье показан хороший образец использования InheritedWidget
. Когда я размещаю унаследованный виджет на уровне MaterialApp, дочерние элементы не обновляются при изменении состояния аутентификации (я уверен, что делаю это неправильно)
FirebaseUser user;
Future<Null> didChangeDependency() async {
super.didChangeDependencies();
User currentUser = await firebaseAuth.currentUser();
setState(() => user = currentUser);
}
@override
Widget build(BuildContext context) {
return new UserContext(
user,
child: new MaterialApp(
title: 'TC Stream',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new LoginView(title: 'TC Stream Login', analytics: analytics),
routes: routes,
),
);
}
FutureBuilder
FutureBuilder также кажется достойным вариантом, но, похоже, требует много работы для каждого маршрута. В частичном примере ниже _authenticateUser()
получает состояние пользователя и настройки по завершении.
@override
Widget build(BuildContext context) {
return new FutureBuilder<FirebaseUser>(
future: _authenticateUser(),
builder: (BuildContext context, AsyncSnapshot<FirebaseUser> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return _buildProgressIndicator();
}
if (snapshot.connectionState == ConnectionState.done) {
return _buildPage();
}
},
);
}
Буду признателен за любые советы по шаблонам передовой практики или ссылки на ресурсы для использования в качестве примеров.