-
-
Notifications
You must be signed in to change notification settings - Fork 207
fix: Adds support for SharedPreferencesAsync #1164
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
base: main
Are you sure you want to change the base?
Conversation
I can confirm that this issue exists, as I encountered this as well in a recent project, but didn't have the time to investigate more and come up with a pr. At that time, I solved it by manually providing my own storage implementation using the async shared preferences. |
Pull Request Test Coverage Report for Build 14823893141Warning: This coverage report may be inaccurate.This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.
Details
💛 - Coveralls |
I thought of another solution like this : Code/// A [LocalStorage] implementation that implements SharedPreferences as the
/// storage method.
class SharedPreferencesLocalStorage extends LocalStorage {
late final SharedPreferences _prefs;
SharedPreferencesLocalStorage({required this.persistSessionKey});
final String persistSessionKey;
static const _useWebLocalStorage =
kIsWeb && bool.fromEnvironment("dart.library.js_interop");
@override
Future<void> initialize() async {
if (!_useWebLocalStorage) {
WidgetsFlutterBinding.ensureInitialized();
_prefs = await SharedPreferences.getInstance();
}
}
@override
Future<bool> hasAccessToken() async {
if (_useWebLocalStorage) {
return web.hasAccessToken(persistSessionKey);
}
return _prefs.containsKey(persistSessionKey);
}
@override
Future<String?> accessToken() async {
if (_useWebLocalStorage) {
return web.accessToken(persistSessionKey);
}
return _prefs.getString(persistSessionKey);
}
@override
Future<void> removePersistedSession() async {
if (_useWebLocalStorage) {
web.removePersistedSession(persistSessionKey);
} else {
await _prefs.remove(persistSessionKey);
}
}
@override
Future<void> persistSession(String persistSessionString) {
if (_useWebLocalStorage) {
return web.persistSession(persistSessionKey, persistSessionString);
}
return _prefs.setString(persistSessionKey, persistSessionString);
}
}
/// A [LocalStorage] implementation that implements SharedPreferencesAsync as the
/// storage method.
class SharedPreferencesAsyncLocalStorage extends LocalStorage {
late final SharedPreferencesAsync _prefs;
SharedPreferencesAsyncLocalStorage({required this.persistSessionKey});
final String persistSessionKey;
static const _useWebLocalStorage =
kIsWeb && bool.fromEnvironment("dart.library.js_interop");
@override
Future<void> initialize() async {
if (!_useWebLocalStorage) {
WidgetsFlutterBinding.ensureInitialized();
_prefs = SharedPreferencesAsync();
}
}
@override
Future<bool> hasAccessToken() async {
if (_useWebLocalStorage) {
return web.hasAccessToken(persistSessionKey);
}
return _prefs.containsKey(persistSessionKey);
}
@override
Future<String?> accessToken() async {
if (_useWebLocalStorage) {
return web.accessToken(persistSessionKey);
}
return _prefs.getString(persistSessionKey);
}
@override
Future<void> removePersistedSession() async {
if (_useWebLocalStorage) {
web.removePersistedSession(persistSessionKey);
} else {
await _prefs.remove(persistSessionKey);
}
}
@override
Future<void> persistSession(String persistSessionString) {
if (_useWebLocalStorage) {
return web.persistSession(persistSessionKey, persistSessionString);
}
return _prefs.setString(persistSessionKey, persistSessionString);
}
} where the dev has to opt-in for I didn't choose this implementation in my PR because the two classes are pretty much the same except for shared prefs init. |
I think CI test fails because with Flutter 3.19 the resolvable |
What kind of change does this PR introduce?
It's both a bug fix and feature.
9 months ago with version 2.3.0,
shared_preferences
package addedSharedPreferencesAsync
andSharedPreferencesWithCache
to replace the legacy (and deprecated in future)SharedPreferences
. See hereSupabase flutter uses by default the legacy one with
SharedPreferencesLocalStorage
.Problem is that on some platform like Windows, the legacy one and new one are not compatible. If the developer made the migration to
SharedPreferencesAsync
then the supabase's local storage is broken.Example :
I'm using
SharedPreferencesAsync
in my app. After sign in, thesb-x-auth-token
is saved insaved-preferences.json
by supabase'sSharedPreferences
. After that, any call to my app'sSharedPreferencesAsync
will overwrite the token and user have to sign in on next app launch. In practice it can lead to sign in every time he opens the app if you use shared preferences frequently in your code.What is the new behavior?
I added a boolean flag
useSharedPreferencesAsync
toSharedPreferencesLocalStorage
. There wasn't very much changes as every methods are already async in LocalStorage interface.If you prefer two distinct classes
SharedPreferencesLocalStorage
andSharedPreferencesAsyncLocalStorage
I can do this