Мой вопрос заключается в том, как управлять пользовательской информацией в приложении Flutter, связанном с Firebase, с использованием Provider.
Мое приложение запрашивает псевдо-регистрацию. Я должен буду хранить это псевдо в Firestore. Пользователь регистрируется анонимно, когда он впервые открывает приложение. У меня нет проблем с входом / регистрацией / преобразованием анонимного пользователя в пользователя электронной почты, и у меня нет проблем с чтением и записью данных в firestore (в коллекции «users», документ «uidOfFirebaseUser»). Проблема в том, как управлять информацией о пользователе, чтобы получить псевдо-информацию о подключенном в данный момент пользователе.
Изначально я думал, что мне придется управлять 2 StreamProvider, один из которых будет простым Firebase FirebaseAuth.instance. onAuthStateChanged
StreamProvider<FirebaseUser>(
create: (context) => FirebaseAuth.instance.onAuthStateChanged),
Второй StreamProvider потребует UID пользователя, чтобы я мог получить предыдущий StreamProvider, чтобы синхронизироваться с коллекцией «пользователи» и документ «UID» пользователя, чтобы получить псевдо
снимок экрана пожарного магазина
class DatabaseService {
final String uid;
DatabaseService({@required this.uid});
Stream<User> streamUser() {
return Firestore.instance
.collection('users')
.document(uid)
.snapshots()
.map((snap) => User.fromMap(snap.data));
}
//
class User {
final String uid;
final bool isAnonymous;
final String pseudo;
final String email;
User({@required this.uid, @required this.isAnonymous, this.pseudo, this.email});
factory User.fromMap(Map data) {
return User(
uid: data['uid'],
isAnonymous: data['isAnonymous'],
pseudo: data['pseudo'] ?? 'No pseudo',
email: data['email'] ?? 'No email',
);
}
Чтобы заставить эти два StreamProvider работать вместе, я реализовал код ниже в мой main.dart, это метод сборки класса MyApp (void main () => runApp (MyApp ()))
return MultiProvider(
providers: [
StreamProvider<FirebaseUser>(
create: (context) => FirebaseAuth.instance.onAuthStateChanged),
ChangeNotifierProvider<Loading>(create: (context) => Loading()),
// another provider that working fine, not the purpose of the question
],
child: Consumer<FirebaseUser>(builder: (context, firebaseUser, child) {
return StreamProvider<User>(
create: (context) =>
firebaseUser != null
? DatabaseService(uid: firebaseUser.uid).streamUser()
: null,
child: MaterialApp( ...
Но эта реализация глючит, когда я выхожу, страница пользователя не перестраивать, или var user = Provider.of (context); на странице пользователя возвращает ноль, пока есть документ Firebase с UID. Я не знаю, стоит ли мне использовать ProxyProvider вместо провайдера или оставить два StreamProvider, но как заставить их работать вместе.
Спасибо за потраченное время, Дмитрий