【问题标题】:StreamProvider and FirebaseStreamProvider 和 Firebase
【发布时间】:2021-09-25 14:29:03
【问题描述】:
void main() async {
  ...
  final AuthenticationProvider authenticationProvider = AuthenticationProvider();
  await authenticationProvider.initialize();
  runApp(
    MultiProvider(
      providers: [
        Provider<AuthenticationProvider>(create: (_) => authenticationProvider),
        StreamProvider<UserModel>(
          create: (_) => authenticationProvider.currentUser,
          initialData: UserModel(
            id: '',
            email: '',
            displayName: '',
            photo: null,
            premium: false,
            travels: [],
          ),
        )
      ],
      child: MiRoulotte(),
    ),
  );
}

我创建了一个提供程序,它使用当前用户数据生成一个流,当用户退出或登录时,这些数据会发生变化,但数据不会改变。当我退出时,流应该为空,然后当我登录时,流应该是用户数据。

class AuthenticationProvider {
  Stream<UserModel>? _currentUser;
  Stream<UserModel>? get currentUser => this._currentUser;

  initialize() async {
    ...
    this._currentUser = FirebaseFirestore.instance
      .collection('users')
      .doc(FirebaseAuth.instance.currentUser?.uid)
      .snapshots()
      .map((user) => UserModel.fromJson(user.data() as Map<String, dynamic>));
    ...
  }

  Future signIn({required String email, required String password}) async {
    ...
    this._currentUser = FirebaseFirestore.instance
      .collection('users')
      .doc(userCredential.user?.uid)
      .snapshots()
      .map((user) => UserModel.fromJson(user.data() as Map<String, dynamic>));
    ...
  }


  Future signOut() async {
    ...
    this._currentUser = null;
    ...
  }
}

【问题讨论】:

    标签: firebase flutter dart stream provider


    【解决方案1】:

    您实际上并不希望您的Stream 成为null,而是让它发出一个null 值。 AuthenticationProvider 可以有一个 StreamController,您可以使用它将当前用户对象的新值添加到流中。

    class AuthenticationProvider {
      final StreamController _controller = SteamController<UserModel?>();
      Stream<UserModel?> get userStream => _controller.stream;
    
      Future<void> initialize() async {
        final user = // get usermodel from firebase
        _controller.add(user);
      }
    
      Future<void> signIn({required String email, required String password}) async {
        ...
        final user = // get usermodel from firebase
        _controller.add(user);
      }
    
      void signOut() {
        _controller.add(null);
      }
    }
    

    别忘了在 dispose 时关闭StreamController:

    // in main
    Provider<AuthenticationProvider>(
      create: (_) => authenticationProvider,
      dispose: (provider) => provider.dispose(),
    ),
    
    // in AuthenticationProvider
    void dispose() {
      _controller.close();
    }
    

    【讨论】:

    • 但是来自 firebase 的用户模型是一个流,当用户更改他的个人资料时会通知。我这样做,但我不知道是否是最好的形式。 FirebaseFirestore.instance.collection('users').doc(FirebaseAuth.instance.currentUser?.uid).snapshots().listen((DocumentSnapshot&lt;Map&lt;String, dynamic&gt;&gt; user) =&gt; this._currentUserController.add(UserModel.fromJson(user.data() as Map&lt;String, dynamic&gt;)));
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-15
    • 2020-08-24
    • 1970-01-01
    • 1970-01-01
    • 2020-05-01
    • 2021-11-15
    • 2020-04-29
    相关资源
    最近更新 更多