rrousselGit / riverpod

A reactive caching and data-binding framework. Riverpod makes working with asynchronous code a breeze.
https://riverpod.dev
MIT License
6.25k stars 956 forks source link

Integrate with Flutter's restoration API #1313

Closed rrousselGit closed 1 month ago

rrousselGit commented 2 years ago

Related to https://github.com/rrousselGit/river_pod/issues/1032 and https://github.com/rrousselGit/river_pod/pull/1312

rrousselGit commented 2 years ago

cc @TimWhiting @North101

rrousselGit commented 2 years ago

Related to the PR made by @North101:

I do not like the idea of having a new provider type. RestorableProvider, to me, does not make sense. Restoration isn't something we want as a separate provider, but rather as a feature that all existing providers would have

We want a restorable FutureProvider & co

rrousselGit commented 2 years ago

I don't like the idea of relying so much on the Flutter API either

We likely want to abstract this feature such that it is usable in pure Dart. And I don't like the usability of the current restoration API

In particular, I think an important question is, do we need to do anything at all for restoration if we have https://github.com/rrousselGit/river_pod/issues/1032? I personally would expect https://github.com/rrousselGit/river_pod/issues/1032 to take care of restoration use-cases already.

TimWhiting commented 2 years ago

The state restoration api design document discusses 3 types of state: http://flutter.dev/go/state-restoration-design

  1. Domain state - Actual domain data, usually stored in some sort of database / local cache, controlled by state management techniques
  2. Session state - IDs into the current view of domain state, TextField contents, scroll position, navigation state, etc
  3. Transient UI state - Animations etc.

The state restoration api is for use case 2 according to the document (there are size limits to what can be saved and it is not meant to be a local cache, just a transient cache between app startups). 3 is almost never important to be saved

When I think of riverpod providers I think of them as both 1 & 2. In the state restoration design document it mentions that the line between 1 & 2 is blurry, and with cloud computing and resuming workflows on multiple computers often 2 is becoming more a part of 1. Additionally since 2 is just a 'transient cache', I believe a local cache can cover that use case as well.

As such I believe #1032 covers the majority of restoration use cases.

There is one distinction that must be considered though. The state restoration API is fully synchronous, meaning that when closing an app it will be able to save state that a local cache might not (a Future might not be completed on app shutdown), and it can directly resume to a particular page or state without going through a loading state. However there is a space constraint as well for data saved this way.

I think it is important to give users an option to use the state restoration API so that they can resume a session synchronously (for example navigation state), but recommend for users to not store any large objects using state restoration.

However, I agree with @rrousselGit that it should work regardless of the type of provider. (We should not create new providers that are named differently). And I feel like it would be good to allow more control over the restoration. For example in a navigation provider you might not want to restore particular routes (if the user's auth token has expired). Additionally you might not want to persist particular states (loading?). As such, I believe a ref based api to be most flexible.

I'm not sure if it would be best to develop this together with #1032 and have just a parameter to control if it is stored with the restoration api or to a local cache, or if it should be a separate feature.

rrousselGit commented 2 years ago

I think it is important to give users an option to use the state restoration API so that they can resume a session synchronously (for example navigation state), but recommend for users to not store any large objects using state restoration.

Do we really need the restoration API for this?

I would expect the persistent API to be enough. While it is asynchronous, folks can handle the loading state if necessary.

knaeckeKami commented 1 year ago

A nice thing about the restoration API is that you have less risk of storing invalid state that puts the app in unexpected state.

With real persistence, you have to think about the structure of your persisted data, how to handle backwards compatibility when adding or removing fields etc.

State restoration is more transient than that, if the user updates the app or manually closes it, the state will not be restored and the app will start from scratch.

peterweb2005 commented 1 year ago

thanks

any today's solution? or workaround stub?

https://github.com/flutter/samples/tree/main/veggieseasons offical flutter solution use "provider", eg: MultiProvider, that we should upgrade to riverpod

thanks

EDIT

current approach, just watch the

ChangeNotifierProvider.value(
          value: _appState.value,
        )

, then remove the MultiProvider

rrousselGit commented 1 month ago

I have no plan to use Flutter's restoration API after-all.

Riverpod is not really for Transient UI state ; which is the main purpose of the restoration API. Offline support should be enough.