如何在另一个 Provider 中侦听 StreamProvider 的值而不是重复

问题描述

我想使用 Riverpod 的 StreamProvider 实时收听 firebase 集合,并将值读入另一个提供程序,但我尝试过的一切都不起作用。

/// StreamProvider
final firstProvider = StreamProvider.autodispose((ref) async* {
  final stream = FirebaseFirestore.instance
      .collection('someCollection')
      .orderBy('timestamp',descending: true)
      .snapshots()
      .distinct();

  await for (final value in stream) {
    print('value: $value');
    yield value;
  }
}

final secondProvider = FutureProvider.autodispose((ref) async {
  final first_provider = await ref.watch(firstProvider);
  print(first_provider .whenData((value) => value.docChanges.length));
  ...
});

我认为通过使用 docChanges 我只会获得新数据,但相反,它会在每次重建时重复。

对我做错了什么有任何想法吗?

解决方法

您的提供商很好。但是,docChanges 返回自上一个快照以来更改的文档数组,如果它是第一个快照,则将包含所有文档。

您在提供程序上使用了 autoDispose 修饰符。因此,如果您正在读取您的提供者的小部件(或其他提供者等)被处置,您的提供者也将被处置。这将导致从您的数据库中重新读取,从而导致 docChanges 返回所有文档。

尝试删除 autoDispose 修饰符,看看会发生什么。

,

如果有人遇到同样的问题,我会通过设置 maintainState 修饰符提供的额外属性 autoDispose 来解决。

final firstProvider = StreamProvider.autoDispose((ref) async* {
  final stream = FirebaseFirestore.instance
      .collection('someCollection')
      .orderBy('timestamp',descending: true)
      .snapshots()
      .distinct();
  
  ref.mantainstate = true;

  await for (final value in stream) {
    print('value: $value');
    yield value;
  }
}