将FirebaseUser映射到自定义User对象

时间:2020-06-11 13:09:07

标签: firebase flutter dart google-cloud-firestore flutter-provider

我有一个Flutter应用程序,其中正在使用StreamProvider监听Firebase的身份验证更改,以显示正确的屏幕。我想做的就是将FirebaseUser映射到自定义User对象(该对象将从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(...)

2 个答案:

答案 0 :(得分:2)

首先,从自定义模型开始,并确定您想要的东西,在这种情况下,我将简单地获得 uid

用户模型

 class User {
      final String uid;

      User({ this.uid });
    }

AuthService

// Create user object based on FirebaseUser
  User _customModelForFirebaseUser(FirebaseUser user) {
    return user != null ? User(uid: user.uid) : null;
  }

  // auth changed user stream
  Stream<User> get user {
    return _auth.onAuthStateChanged
      .map(_customModelForFirebaseUser)
  }

我的应用

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamProvider<User>.value(
      value: AuthService().user,
      child: MaterialApp(
        home: Wrapper(),
      ),
    );
  }
}

然后您可以从任何地方访问它,就像这样:

 @override
      Widget build(BuildContext context) {

        final user = Provider.of<User>(context);
}

答案 1 :(得分:1)

我使用 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']);
    }
}