Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatic persistence? #44

Open
wujek-srujek opened this issue Feb 15, 2021 · 10 comments
Open

Automatic persistence? #44

wujek-srujek opened this issue Feb 15, 2021 · 10 comments
Assignees
Labels
enhancement New feature or request

Comments

@wujek-srujek
Copy link

wujek-srujek commented Feb 15, 2021

Is your feature request related to a problem? Please describe.
I use a StateNotifier for state management (with riverpod) and I got it to work. However, now I would like to persist the state so that it survives application restarts.

Describe the solution you'd like
Libraries that I have used before, like redux or bloc, both support automatic persistence, normally as separate packages (redux_persist and hydrated_bloc). I have looked around and it seems that there is nothing out of the box for state_notifier. I understand it is not hard to do myself, but I expect a lot of people to have to write very similar code to solve this. Would it be possible to also have some kind of automatic persistence?

For serialization on state changes, I think the easiest way that would work for all StateNotifiers would be to do it in a listener - whenever it is fired, it schedules a write. I suppose this could be a separate package like state_notifier_persistence, which offers some abstraction layer (like an abstract Storage interface, with a possible default implementation with hive (it seems to be the go-to library for things like this in Flutter), possibly in yet another package, like state_notifier_persistence_hive. state_notifier_persistence would also provide the said listener (PersistingListener?) which takes an instance of Storage and uses it.

For deserialization (i.e. when a StateNotifier is created and there already exist state in storage) I don't have a nice API in mind yet. One option would be to have a mixin that provides storage and overrides the state getter and if the state is null, it uses storage to read it from disk. I beliveve this is what hydrated_bloc does.

Describe alternatives you've considered
I've implemented it myself for my application (very dirty, very ugly for now, no abstraction over hive etc., it is just a PoC). As far as I know, there are no alternatives to this, except migrating away to other state-management libraries.

@wujek-srujek wujek-srujek added the enhancement New feature or request label Feb 15, 2021
@rrousselGit
Copy link
Owner

That's something I plan to implement (in riverpod, not statenotifier). But it requires refinement. I don't want to release a bad API
So it's going to take a while

@wujek-srujek
Copy link
Author

Why not state_notifier? This would make it broadly available even without riverpod.

@rrousselGit
Copy link
Owner

RIverpod has more to restore than just statenotifiers. For example we may want to persist a Future/StreamProvider

@wujek-srujek
Copy link
Author

Right. But why not implement persistence for state_notifier so that it works for state_notifier without riverpod, and then implement in riverpod whatever needs to be persisted, possibly with some further improvements for state_notifier? It seemed to me you wanted people to use state_notifier no matter if they used riverpod or not (but I can imagine you would like all of us to use riverpod as well ;-)), and this would also help adoption.

Bottomline is: if you do it in riverpod only, there will be this strange situation where state_notifier will be kind of a standalone library, but will need riverpod for persistence, but riverpod is much more than that and not everybody will like/use it and be willing to include just to get persistence for state_notifier. In this case I would question if state_notifier is the way to go as with each such decision it will force me more and more towards riverpod, which I might not necessarily like (well, I personally do, but not everyone will).

@rrousselGit
Copy link
Owner

I don't like the idea of shipping a solution if I haven't thought all the cases through.

A quick API may work in the sort-term. But it may require a large breaking change or the coexistence of two competing APIs within the same library.
I wouldn't want StateNotifier to have one way of doing deserialisation and Riverpod have another way for example. That'd be confusing

@wujek-srujek
Copy link
Author

That's not at all what I am saying, I don't want to use a half-assed API either. I don't know where this comes from, seriously. If half a year is necessary to implement a good solution, so be it. What I was arguing was that state_notifier, as a standalone package independent of riverpod, should have its own automatic persistence, is all.

@rrousselGit
Copy link
Owner

Ah sorry, I wanted to say that I don't think it is possible to have the best API possible just with StateNotifier.

@venkatd
Copy link

venkatd commented Mar 18, 2021

Just another perspective, but I like that StateNotifier is a robust and focused library. Adding persistence to it would increase its scope for a feature that many people may not use.

Implementing persistence is use case specific. Where do you store the persisted data? How do you serialize the state? When do you persist and when do you restore? Do you debounce this logic? It all depends on the application and I bet it's varies a lot depending on the app.

On the other hand, implementing something like PersistentStateNotifier that extends/wraps StateNotifier and persists data for your specific app is likely not a lot of code.

Perhaps you could share your use case? We have something like this lying around in our codebase that I can share when I get a chance.

@wujek-srujek
Copy link
Author

wujek-srujek commented Mar 19, 2021

That's why I said that it could be in a separate package, like a lot of state management libraries do, e.g. hydrated_bloc or redux_persist_flutter. It is possible to parameterize all that you mention, as the mentioned libraries, and many more, were able to do and came up with an API for it (which most of the time is some kind of Storage abstraction with a few methods like put, get etc., and various implementations, with Hive and JSON being very popular choices).

Of course I can implement the PersistentStateNotifier myself, the point is - everybody will need to do it if they need state persistence, an everybody will do it differently, which is unnecessary effort. Also, everybody will have their own little bugs; if it is in a package that is used by many, this would not happen as often as it would be battle-tested by real world apps.

I'm arguing that any state management library without the ability to persist the state out-of-the-box isn't complete. But anyways, yeah, I have already understood that you don't want this for whatever reason, so I guess the topic can be closed.

@tim-smart
Copy link

I stumbled upon this issue looking for a generic persistence layer on top of riverpod.

As a result, I have started a proof of concept solution. You can view the working test case here: https://github.com/tim-smart/riverpod_persistence/blob/main/test/riverpod_persistence_test.dart

@rrousselGit rrousselGit self-assigned this May 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants