[英]How to handle complex state with Riverpods StateNotifierProvider
[英]How to update state in a fcm handler with StateNotifierProvider?
在我的 Flutter 应用程序中,我需要能够对传入的 fcm 消息做出反应,这些消息可以通过在其数据有效负载中具有相应的键/值对来指示应用程序到 go 不同的导航选项卡。 当前,选定的索引存储在有状态小部件中,该小部件还托管底部导航栏:
@override
Widget build(BuildContext context) {
presentTicketsModel = ref.watch(presentTicketsModelProvider);
contractsModel = ref.watch(contractsModelProvider);
return Scaffold(
body: PersistentTabs(
currentTabIndex: index,
screenWidgets: buildPages(),
),
bottomNavigationBar: NavigationBar(
height: 60,
selectedIndex: index,
onDestinationSelected: (index) => setState(() {
this.index = index;
}),
destinations: _buildNavigationDestinations(),
),
);
}
面对新的挑战,我考虑将 state 索引移动到单独的 object 中,并使用 Riverpod 的 StateNotifierProvider 提供 state object,如官方文档 ( https://riverpod.deviders/docs ) 中所述。
我不明白的是:以下服务 class(侦听传入的 fcm 消息)如何获取 state object 并更新索引,以便观察视图 class 得到通知并可以切换到目标导航选项卡?
class PushNotificationService {
final fcm = FirebaseMessaging.instance;
Future initialise() async {
print('initialising push notification service...');
}
/// foreground handler
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print('onMessage: $message');
// here the state change would be done
});
/// handler if the app has been opened from a background state
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
print('onMessageOpenedApp: $message');
});
}
}
或者以不同的方式询问:该服务 class 如何通过 ProviderReference 以访问提到的 state object 并更改索引值?
该服务目前在 GetIt 注册为一个懒惰的 singleton:
GetIt locator = GetIt.instance;
void setupLocator() {
locator.registerLazySingleton(PushNotificationService.new);
}
initialise
方法可以有一个Ref
参数,如下所示:
class PushNotificationService {
final fcm = FirebaseMessaging.instance;
Future initialise(WidgetRef ref) async {
print('initialising push notification service...');
}
/// foreground handler
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
// Use ref.read here -> ref.read();
});
/// handler if the app has been opened from a background state
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
print('onMessageOpenedApp: $message');
});
}
}
然后你可以在调用初始化时传递一个ref。
PushNotificationService.initialise(ref);
如果您要在小部件中调用
initialise
,请使用WidgetRef
而不是Ref
WidgetRef
)MyApp
成为ConsumerStatefulWidget
PushNotificationService.initialise(ref);
在initState
void main() {
runApp(const ProviderScope(child: MyApp()));
}
class MyApp extends ConsumerStatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
ConsumerState<ConsumerStatefulWidget> createState() => _MyAppState();
}
class _MyAppState extends ConsumerState<MyApp> {
@override
initState(){
PushNotificationService.initialise(ref);
super.initState();
}
class _MyAppState extends ConsumerState<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "App",
home: Home(),
);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.