如何在 Flutter 中将 Stream 转换为 Listenable?

Flo*_*ser 8 dart firebase flutter gorouter riverpod

我试图弄清楚如何利用 Firebase 的流作为go_router包中参数onAuthStateChanges()中的可监听对象,以便在 authState 更改时进行重定向。此外,我正在使用flutter_riverpod进行状态管理。refreshListenable

到目前为止我的代码看起来像这样:

我创建了一个简单的 AuthService 类(缩减到最重要的部分):

abstract class BaseAuthService {
  Stream<bool> get isLoggedIn;
  Future<bool> signInWithEmailAndPassword({ required String email, required String password });
}

class AuthService implements BaseAuthService {
  final Reader _read;

  const AuthService(this._read);

  FirebaseAuth get auth => _read(firebaseAuthProvider);

  @override
  Stream<bool> get isLoggedIn => auth.authStateChanges().map((User? user) => user != null);

  @override
  Future<bool> signInWithEmailAndPassword({ required String email, required String password }) async {
    try {
      await auth.signInWithEmailAndPassword(email: email, password: password);
      return true;
    } on FirebaseAuthException catch (e) {
      ...
    } catch (e) {
      ...
    }

    return false;
  }
Run Code Online (Sandbox Code Playgroud)

接下来我创建了这些提供程序:

final firebaseAuthProvider = Provider.autoDispose<FirebaseAuth>((ref) => FirebaseAuth.instance);

final authServiceProvider = Provider.autoDispose<AuthService>((ref) => AuthService(ref.read));
Run Code Online (Sandbox Code Playgroud)

如前所述,我想以某种方式监听这些 authChanges 并将它们传递给路由器:

final router = GoRouter(
    refreshListenable: ???
    redirect: (GoRouterState state) {
        bool isLoggedIn = ???
        
        if (!isLoggedIn && !onAuthRoute) redirect to /signin;
    }
)
Run Code Online (Sandbox Code Playgroud)

Rez*_*ari 15

根据go_router文档,您可以简单地使用以下方法: https://gorouter.dev/redirection#refreshing-with-a-stream

GoRouterRefreshStream(_fooBloc.stream)
Run Code Online (Sandbox Code Playgroud)

更新:2022 年 9 月 20 日

该类已从 go_router 5.0 中删除,并且 go_router 中没有提供替代类。原因是该类与路由无关,不应该包含在 go_router 中。要迁移使用此类的现有应用程序,可以将该类复制到其代码中并直接拥有实现。

GoRouterRefreshStream(_fooBloc.stream)
Run Code Online (Sandbox Code Playgroud)