@riverpodFuture<UserModel>userById(Refref,Stringuid)async{// 1. Listen to the cache safely
finaluserServiceState=ref.watch(userServiceProvider);finaluserInCache=userServiceState.users[uid];if(userInCache!=null){returnuserInCache;}// 2. If missing, fetch from the network without updating the master map inside this frame loop.
// Instead of letting the Service change its master map instantly,
// we fetch the network data cleanly in isolation first.
finalfetchedUser=awaitAdapterRegistry.user.get(uid);// 3. Defer the state cache update to the next microtask frame.
// This satisfies Riverpod's lifecycle rules completely.
Future.microtask((){if(ref.mounted){ref.read(userServiceProvider.notifier).addUserToCache(fetchedUser);}});returnfetchedUser;}
Watching the provider
ref.watch(networkServiceProvider).isOnline
This watches the NetworkServiceState object (the value returned by the build method).
How it works: Every single time the network state updates (e.g., swapping from online to offline), a brand new NetworkServiceState object is emitted.
The result: Riverpod detects this new state object, extracts the .isOnline boolean, and triggers a rebuild of your convenience provider (and any UI components listening to it).
When to use it: Use this when you want your convenience provider to actively react and update whenever the network connection changes.
This watches the NetworkService controller class instance itself.
How it works: In Riverpod, the notifier class instance (NetworkService) is instantiated exactly once when the provider is first initialized and is marked as persistent.
The controller instance itself never changes, even when its internal state updates.
The result: Because the controller instance never changes, ref.watch(…notifier) reads the value once and then stops listening for changes.
Your convenience provider will completely miss subsequent network changes and will get stuck on whatever the initial boot value was.
When to use it: You should almost never use ref.watch(…notifier) to read a value.
The .notifier syntax should strictly be used with ref.read when you want to call a method
Anti-pattern. Avoid using .notifier to grab state fields.
Corrected Convenience Provider Code
To ensure your convenience providers are fully reactive and update seamlessly, update them to watch the state directly:
/// Quick access to online status (Fully Reactive)
@riverpod
bool isOnline(Ref ref) {
// Watches the state object, so this triggers whenever network status changes
return ref.watch(networkServiceProvider).networkStatus == NetworkStatus.online;
}