0

FirebaseAuth用于身份验证,并定义了以下提供程序:

final _authStateChangesProvider = StreamProvider<User>(
    (ref) => ref.watch(authServiceProvider).authStateChanges);

数据库依赖于用户,所以我只能在用户登录后创建它。问题是数据库创建是异步的,所以它的提供者必须是 FutureProvider。

final databaseFutureProvider = FutureProvider<Database>((ref) {
  final authStateChange = ref.watch(_authStateChangesProvider);
  final user = authStateChange.data?.value;
  if (user != null) {
    return FirestoreDatabase.create(user: user);
  }
  throw UnsupportedError("The database cannot be accessed before the sign-in");
});

这将使整个应用程序的代码更加繁琐。我想让应用程序的代码更databaseFutureProvider简洁。Provider怎么可能做到?

编辑

最好让数据库创建成为身份验证过程的一部分,这样authStateChangesProvider只有在数据库创建后才会触发。类似于以下内容:

final authStateChangesProvider = FutureProvider<User>((ref) {
  final authStateChanged = ref.watch(_authStateChangesProvider);
  final user = authStateChanged.data?.value;
  if (user != null) {
    // await the creation of the database provider
  }
  return user;
});

这样,只有authStateChangesProvider将成为 FutureProvider。但我对 Riverpod 还很陌生,我不确定是否以及如何在另一个提供程序中创建一个提供程序。

4

1 回答 1

1

我想出了一个可能不是最好的解决方案,但我会在这里发布,以便其他人可以从中受益或希望可以改进它。

我创建了一个新的ScopedProvider.

final databaseProvider =
    ScopedProvider<Database>((ref) => throw UnimplementedError());

然后我创建了一个新的小部件,它将被放置在需要同步访问数据库的小部件树的顶部。此小部件将仅在创建数据库时显示加载视图,然后覆盖databseProvider.

class DatabaseWidgetBuilder extends ConsumerWidget {
  final Widget Function(Database) childBuilder;

  DatabaseWidgetBuilder(
      {Key key, @required Widget Function(Database) this.childBuilder})
      : super(key: key);

  @override
  Widget build(BuildContext context, ScopedReader watch) {
    final databaseAsyncValue = watch(databaseFutureProvider);
    return databaseAsyncValue.when(
      data: (database) => ProviderScope(
        overrides: [databaseProvider.overrideAs((watch) => database)],
        child: childBuilder(database),
      ),
      loading: () => Scaffold(
        body: Center(child: CircularProgressIndicator()),
      ),
      error: (_, __) => Scaffold(
        body: Center(child: Text("Database Error")),
      ),
    );
  }
}
于 2021-02-19T15:20:23.353 回答