首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >刷新/重置StreamProvider -颤振火库

刷新/重置StreamProvider -颤振火库
EN

Stack Overflow用户
提问于 2022-04-16 05:37:24
回答 2查看 399关注 0票数 1

在我的应用程序中,我有以下的提供者。

代码语言:javascript
复制
@override
  Widget build(BuildContext context) {
    return OverlaySupport.global(
      child: MultiProvider(
        providers: [userLoggedIn, currentUserData],
        child: MaterialApp(...)))
}
代码语言:javascript
复制
  var userLoggedIn = StreamProvider<User?>.value(
      value: FirebaseAuth.instance.authStateChanges(), initialData: null);

  var currentUserData = StreamProvider<FrediUser>.value(
    updateShouldNotify: (_, __) => true,
    initialData: FrediUser(
      loginProvider: '',
      email: '',
      admin: false,
        profileSettings: [],
        profileChips: [],
        profileStats: [],
        id: 'loading',
        imageUrl: 'loading',
        bio: 'loading',
        username: 'loading'),
    value: currentUserID != null ? currentUserDataStream() : null,
  );

问题

当用户注销(或首次登录)时,提供程序是:

包含旧用户数据的

  • (直到重新启动(当提供者再次被调用并重新加载)
  • Null或空,因为以前没有用户。

我想做的是,一旦有了新用户,就重新刷新或调用Stream Providers,或者在用户注销后删除所有数据。

谢谢!

EN

回答 2

Stack Overflow用户

发布于 2022-04-21 00:30:38

你可以听到这样的状态变化。

代码语言:javascript
复制
FirebaseAuth.instance
  .authStateChanges()
  .listen((User? user) {
    if (user == null) {
      print('User is currently signed out!');
    } else {
      print('User is signed in!');
    }
  });
票数 1
EN

Stack Overflow用户

发布于 2022-04-21 11:00:52

我一直面临着与您类似的问题,我想出了一个解决方案--尽管不确定它是否符合Provider体系结构。

问题

我有一个DatabaseService类,它有一个类型为Stream<CustomUser>函数的流函数,我使用它的方式如下:

代码语言:javascript
复制
//--- main.dart ---//

runApp(MultiProvider(
      providers: [
      // ..some other providers.. //

        // data provider
        Provider<DatabaseService?>(
          create: (_) => databaseService,
        ),

        // data provider
        StreamProvider<CustomUser?>(
          create: (context) => databaseService.getCurrUserFromDb(),
          lazy: false,
          initialData: null,
          updateShouldNotify: (_, __) => true,
        ),

      ],
      child: MyApp(
        initPage: initPage,
      )
));

流功能:

代码语言:javascript
复制
//--- database_service.dart ---//

  // gets the user from database and
  // assigns it to the variable _user.
  Stream<CustomUser?> getCurrUserFromDB() async* {
    try {
      CustomUser? currUser;

      if (_user != null) {
        await for (DocumentSnapshot<Object?> event
            in users.doc(user.uid).snapshots()) {
          final jsonMap = event.data() as Map<String, dynamic>;
          currUser = CustomUser.fromJson(jsonMap);
          _user = currUser;
          CustomPreferences.setCurrUser(_user);
          yield currUser;
        }
      }
    } catch (e) {
      rethrow;
    }
  }

databaseService是带有命名构造函数的DatabaseService类。

这是而不是在开始时或流具有新值时导致小部件重建的结果。

解决方案:

StreamController类中创建了一个DatabaseService,当用户在其中签名时,我向StreamController添加了一个getCurrUserFromDB()函数,如下所示

代码语言:javascript
复制
//--- authentication_screen.dart ---//

...
ElevatedButton(
    child: const Text("Sign In"),
    onPressed: () async {
      final user = await AuthService().googleSignIn();
      if (user != null) {
        final dbProvider = context.read<DatabaseService?>();
        await dbProvider?.setInitUser(user, context);
        await dbProvider?.cusUserController
            .addStream(dbProvider.getCurrUserFromDB());
      }
    }),
...

使用setInitUser(CustomUser? user)设置DatabaseService_user变量的值,并使用user获取该变量。

推理

我正在在应用程序的开头创建a StreamProvider,它的源代码StreamController需要有一个流来听,所以我在尝试登录时给出了它。

甚至更简单的解决方案是在DatabaseService类的构造函数中这样做:

代码语言:javascript
复制
//--- database_service.dart ---//

// method to add the stream to controller //
Future<void> addStream() async {
    if (!_cusUserController.isClosed && !_cusUserController.isPaused) {
      await _cusUserController.addStream(getCurrUserFromDB());
    }
  }

// constructor //
DatabaseService._init(CustomUser cusUser) {
    addStream();
    _user = cusUser;
  }

最后要注意的一点是,我没有将Controller声明为final。当我宣布它为final时,流没有更新,所以现在看起来是这样的:

代码语言:javascript
复制
//--- database_service.dart ---//

    StreamController<CustomUser?> _cusUserController = StreamController();

TL;DR

我创建了一个StreamProvider,它在它的create属性中返回一个StreamController,然后在应用程序的生命周期内使用addStream方法给控制器一个流。

对不起,我只是想尽可能清楚地说出来。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71891401

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档