将 FirebaseUser 映射到自定义用户对象
Map FirebaseUser to custom User object
我有一个 Flutter 应用程序,我在其中使用 StreamProvider 监听来自 Firebase 的身份验证更改以显示正确的屏幕。我想做的是将 FirebaseUser 映射到一个自定义用户对象,该对象将从 Firestore 检索,以便可以从小部件树中的任何位置访问它。
有什么办法可以实现吗?
我现在在做什么:
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
Stream<FirebaseUser> get user {
return _auth.onAuthStateChanged;
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamProvider<FirebaseUser>.value(
value: AuthService().user,
child: MaterialApp(...)
首先,从自定义模型开始,然后决定您想要什么,在这种情况下,我只需要 uid
###用户模型###
class CurrentUser {
final String uid;
CurrentUser ({ this.uid });
}
###AuthService###
// Create user object based on FirebaseUser
CurrentUser _customModelForFirebaseUser(User user) {
return user != null ? CurrentUser (uid: user.uid) : null;
}
// auth changed user stream
Stream<CurrentUser > get user {
return _auth.onAuthStateChanged
.map(_customModelForFirebaseUser)
}
###我的应用程序###
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamProvider<CurrentUser >.value(
value: AuthService().user,
child: MaterialApp(
home: Wrapper(),
),
);
}
}
然后你就可以从任何地方访问它了,就像这样:
@override
Widget build(BuildContext context) {
final user = Provider.of<CurrentUser>(context);
}
我使用 https://pub.dev/packages/rxdart 组合并合并了 Firebase 身份验证用户和 Firestore 用户流。
对于身份验证流,我正在使用 userChanges()
来收听所有用户更新。 flatMap()
获取 auth 流,将其转换为 firestore 流并将其与 firestore 流结合,因此现在我们正在监听 auth 更改和 firestore 更改。
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamProvider<UserModel>.value(
value: FirebaseAuth.instance.userChanges().flatMap(
(firebaseUser) => DatabaseService(uid: firebaseUser.uid).userData)),
child: MaterialApp(...)
database.dart
class DatabaseService {
final String uid;
DatabaseService({this.uid});
// get firestore user stream and convert each item into your user object (UserModel in my example)
Stream<UserModel> get userData {
return FirebaseFirestore.instance.collection('users').doc(uid).snapshots()
.map((snapshot) => UserModel.fromMap(snapshot.data()));
user_model.dart
class UserModel {
String field1;
String field2;
UserModel({this.field1, this.field2});
// using factory to create an instance of UserModel
factory UserModel.fromMap(Map data) {
return UserModel(field1: data['field1'], field2: data['field2']);
}
}
我有一个 Flutter 应用程序,我在其中使用 StreamProvider 监听来自 Firebase 的身份验证更改以显示正确的屏幕。我想做的是将 FirebaseUser 映射到一个自定义用户对象,该对象将从 Firestore 检索,以便可以从小部件树中的任何位置访问它。
有什么办法可以实现吗?
我现在在做什么:
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
Stream<FirebaseUser> get user {
return _auth.onAuthStateChanged;
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamProvider<FirebaseUser>.value(
value: AuthService().user,
child: MaterialApp(...)
首先,从自定义模型开始,然后决定您想要什么,在这种情况下,我只需要 uid
###用户模型###
class CurrentUser {
final String uid;
CurrentUser ({ this.uid });
}
###AuthService###
// Create user object based on FirebaseUser
CurrentUser _customModelForFirebaseUser(User user) {
return user != null ? CurrentUser (uid: user.uid) : null;
}
// auth changed user stream
Stream<CurrentUser > get user {
return _auth.onAuthStateChanged
.map(_customModelForFirebaseUser)
}
###我的应用程序###
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamProvider<CurrentUser >.value(
value: AuthService().user,
child: MaterialApp(
home: Wrapper(),
),
);
}
}
然后你就可以从任何地方访问它了,就像这样:
@override
Widget build(BuildContext context) {
final user = Provider.of<CurrentUser>(context);
}
我使用 https://pub.dev/packages/rxdart 组合并合并了 Firebase 身份验证用户和 Firestore 用户流。
对于身份验证流,我正在使用 userChanges()
来收听所有用户更新。 flatMap()
获取 auth 流,将其转换为 firestore 流并将其与 firestore 流结合,因此现在我们正在监听 auth 更改和 firestore 更改。
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamProvider<UserModel>.value(
value: FirebaseAuth.instance.userChanges().flatMap(
(firebaseUser) => DatabaseService(uid: firebaseUser.uid).userData)),
child: MaterialApp(...)
database.dart
class DatabaseService {
final String uid;
DatabaseService({this.uid});
// get firestore user stream and convert each item into your user object (UserModel in my example)
Stream<UserModel> get userData {
return FirebaseFirestore.instance.collection('users').doc(uid).snapshots()
.map((snapshot) => UserModel.fromMap(snapshot.data()));
user_model.dart
class UserModel {
String field1;
String field2;
UserModel({this.field1, this.field2});
// using factory to create an instance of UserModel
factory UserModel.fromMap(Map data) {
return UserModel(field1: data['field1'], field2: data['field2']);
}
}