如何在无Ref/context的类中读取Riverpod Provider配置Firebase流?
解决方案
方案1:将年份流作为参数传入方法(推荐,解耦)
直接让userStream接收外部传入的年份Stream,后端类无需依赖Riverpod,完全解耦。
Stream<DocumentSnapshot> userStream(Stream<String> yearStream) async* { // 监听年份流的变化,每次年份更新时切换Firebase流 await for (final year in yearStream) { yield* FirebaseFirestore.instance .collection(year) .doc("test") .snapshots(); } }
在使用该后端类的Provider中,通过ref.watch获取年份流并传入:
final backendServiceProvider = Provider<BackendService>((ref) => BackendService()); final userStreamProvider = StreamProvider<DocumentSnapshot>((ref) { // 获取年份的Stream final yearStream = ref.watch(yearFromProvider2).stream; final backendService = ref.watch(backendServiceProvider); return backendService.userStream(yearStream); });
方案2:传入ProviderContainer(适合需要类内部自主获取的场景)
给后端类的构造函数传入ProviderContainer,通过容器直接监听Provider的变化:
class BackendService { final ProviderContainer _container; BackendService(this._container); Stream<DocumentSnapshot> userStream() async* { // 监听年份Provider的变化,转为Stream final yearSubscription = _container.listen(yearFromProvider2); try { await for (final year in yearSubscription.asStream()) { yield* FirebaseFirestore.instance .collection(year) .doc("test") .snapshots(); } } finally { // 记得取消订阅避免内存泄漏 yearSubscription.close(); } } }
初始化时传入容器:
void main() { final container = ProviderContainer(); final backendService = BackendService(container); runApp(UncontrolledProviderScope(container: container, child: MyApp())); }
方案3:全局Stream快速临时解决(不推荐大型项目)
如果只是临时快速解决,可以把年份Provider的变化同步到一个全局的StreamController,后端类直接监听这个全局流:
// 全局广播StreamController final _yearStreamController = StreamController<String>.broadcast(); // 在年份Provider中同步更新全局流 final yearFromProvider2 = StateProvider<String>((ref) { const initialYear = "2024"; ref.onDispose(() => _yearStreamController.close()); // 监听年份变化,同步到全局流 ref.listenSelf((_, newYear) => _yearStreamController.add(newYear)); return initialYear; }); // 后端类中使用 Stream<DocumentSnapshot> userStream() async* { await for (final year in _yearStreamController.stream) { yield* FirebaseFirestore.instance .collection(year) .doc("test") .snapshots(); } }
注意:这个方案耦合性高,容易引发内存泄漏和状态管理混乱,仅适合小型项目或临时测试使用。
内容的提问来源于stack exchange,提问作者Dan12314
相关产品推荐
相关产品推荐

