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

Local Storage problem on React Native (MMKV cache) #6348

Closed
lyqht opened this issue Apr 7, 2022 · 5 comments
Closed

Local Storage problem on React Native (MMKV cache) #6348

lyqht opened this issue Apr 7, 2022 · 5 comments
Labels
bug Something isn't working wontfix This will not be worked on

Comments

@lyqht
Copy link
Contributor

lyqht commented Apr 7, 2022

Bug report

Describe the bug

This bug is pretty similar to what is reported in #276, where I'm getting errors like

 ERROR  [TypeError: undefined is not an object (evaluating 'this.localStorage.getItem')]

So far I have developed the login and sign up functionality for my app by ignoring the error, but now that I'm trying to implement the sign out functionality, the following warning stops me from proceeding any further.

 WARN  Possible Unhandled Promise Rejection (id: 8):
TypeError: undefined is not an object (evaluating 'this.localStorage.removeItem')

The solution in #276 is to declare the storage manually as async storage, however I'm using MMKV for storage instead.

I will get the following typescript prompt when I try to set the storage as MMKV.

image

Reading the documentation on initializing the client further, I also tried the following configuration to create the client, but it still tries to access this.localStorage.

const supabase = createClient(supabaseUrl, supabaseKey, {
  autoRefreshToken: false,
  persistSession: false,
  detectSessionInUrl: false,
});

Do I have to swap out my cache provider entirely? or is there a way to work around this? Any help will be appreciated!

To Reproduce

Reference project can be found at Billy.

Expected behavior

  • I would like to continue using MMKV.

System information

  • OS: macOS
  • Platform: React Native
  • Version of supabase-js: ^1.33.2
  • Version of Node.js: 16 LTS
@lyqht lyqht added the bug Something isn't working label Apr 7, 2022
@lyqht
Copy link
Contributor Author

lyqht commented Apr 7, 2022

For anyone who is keen, the workaround that I came up with for using MMKV as cache which helps to remove the errors and warnings

class Cache {
  private storage;
  constructor() {
    this.storage = new MMKV();
    if (__DEV__) {
      initializeMMKVFlipper({default: this.storage});
    }
  }

  // -------------------------------------
  // these methods are added so that the Supabase client can access MMKV as cache

  getItem(key: string) {
    return this.storage.getString(key);
  }

  setItem(key: string, value: string) {
    return this.storage.set(key, value);
  }

  removeItem(key: string) {
    if (this.storage.contains(key)) {
      this.storage.delete(key);
    }
  }
  // -------------------------------------
}

@kiwicopple
Copy link
Member

Thanks for the workaround @lyqht . I'll close this since you've shared that snippet!

To answer your question:

Do I have to swap out my cache provider entirely?

The auth library simply uses the localstorage browser interface, so you can use any storage library which uses the same interface. There are quite a few out there, but if you are using a library that does not adhere to this interface you have two options:

  1. Add another library which does, and "inject" it into supabase-js, like we do in our examples within our docs
  2. Patch your library, like @lyqht did above

@thorwebdev
Copy link
Member

thorwebdev commented Apr 8, 2022

In case helpful, here an example with AsyncStorage: https://github.com/supabase-community/expo-stripe-payments-with-supabase-functions/blob/main/app/lib/supabase.ts#L12-L17

export const supabase = createClient(supabaseUrl, supabaseAnonKey, {
  localStorage: AsyncStorage as any,
  autoRefreshToken: true,
  persistSession: true,
  detectSessionInUrl: false,
});

@vbylen
Copy link

vbylen commented Apr 16, 2022

For anyone using react-native-mmkv this also works:

import { SUPABASE_URL, SUPABASE_ANON_KEY } from './constants';
import { createClient } from "@supabase/supabase-js";
import { MMKV } from 'react-native-mmkv'

const storage = new MMKV({ id: 'supabase-storage' })

const mmkvStorageConfig = {
  setItem: (key, data) => storage.set(key, data),
  getItem: (key) => storage.getString(key),
  removeItem: (key) => storage.delete(key),
}

export const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY, {
  localStorage: mmkvStorageConfig,
  persistSession: true,
  autoRefreshToken: true,
  detectSessionInUrl: false
});

@egor-romanov egor-romanov added the wontfix This will not be worked on label Jun 15, 2022
@bryanltobing
Copy link

For anyone using react-native-mmkv this also works:

in typescript

import 'react-native-url-polyfill/auto';
import { SupportedStorage, createClient } from '@supabase/supabase-js';
import { MMKV } from 'react-native-mmkv';

const storage = new MMKV({ id: 'supabase-storage' });

const mmkvSupabaseSupportedStorage = {
  setItem: (key, data) => storage.set(key, data),
  getItem: (key) => storage.getString(key) ?? null,
  removeItem: (key) => storage.delete(key),
} satisfies SupportedStorage;

export const supabase = createClient(supabaseUrl, supabaseAnonKey, {
  auth: {
    storage: mmkvSupabaseSupportedStorage,
    autoRefreshToken: true,
    persistSession: true,
    detectSessionInUrl: false,
  },
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

6 participants