10

I am storing few user preferences in React Native using AsyncStorage. Now, I need to get those preference from a background service. I can't access AsyncStorage from the Java layer. Is there a way to do it?

In iOS, We can import RCTAsyncLocalStorage.h and call _getValueForKey. But, I can't find a way to do it in Android.

Sriraman
  • 7,658
  • 4
  • 40
  • 60

5 Answers5

7

I have following code which does the job.

import com.facebook.react.modules.storage.AsyncLocalStorageUtil;
import com.facebook.react.modules.storage.ReactDatabaseSupplier;
import android.database.sqlite.SQLiteDatabase;
.....
.....


SQLiteDatabase readableDatabase = null;
readableDatabase = ReactDatabaseSupplier.getInstance(this.getApplicationContext()).getReadableDatabase();
 if (readableDatabase != null) {
    String impl = AsyncLocalStorageUtil.getItemImpl(readableDatabase, "myTableName");
    Log.d(TAG, "impl: " + impl);
  }

====================
and to delete the DB
=====================
SQLiteDatabase database = ReactDatabaseSupplier.getInstance(getContext()).getWritableDatabase();
database.delete(CATALYST_LOCAL_STORAGE, null, null);
Muhammad Riyaz
  • 2,832
  • 2
  • 26
  • 30
  • 1
    I'm using ```redux-persist```, do you have any idea of how can I know the name of ```myTableName``` – Pablo Jan 04 '18 at 19:26
  • 1
    @Pablo I know this is an old post. but if anyone needs to read redux-persist database using this method, database name is "catalystLocalStorage" and key is "persist:root" assuming key name given as root when configuring redux-persist. – Samitha Nanayakkara Apr 27 '20 at 15:16
  • @Pablo "myTableName" is the table name I had defined and created from ReactNative by doing AsyncStorage.setItem("myTableName", JSON.stringify(obj)); and obj here is just a object which has key value pairs. And to access this table created at JS layer, I use above method i mentioned which still works. – Muhammad Riyaz Apr 28 '20 at 08:02
  • Can you highlight what imports are required for this on the Android side? – Amogh Jahagirdar May 30 '20 at 16:53
  • 1
    @MuhammadRiyaz, thanks for posting this. Is a any way to clear the database or value ? – Ankit Jayaprakash Jul 15 '20 at 17:56
  • @AnkitJayaprakash please check the answer I have added delete db snippet which I use. – Muhammad Riyaz Jul 16 '20 at 18:17
  • 1
    @AmoghJahagirdar sorry for late reply. Check out the answer I have updated with imports. – Muhammad Riyaz Jul 16 '20 at 18:18
  • 1
    @AmoghJahagirdar I used the same, but it says No table found with that name. But am able to read the database with that same table name. So I this way ``ReactDatabaseSupplier readableDatabase = ReactDatabaseSupplier.getInstance(context); readableDatabase.clearAndCloseDatabase();`` – Ankit Jayaprakash Jul 16 '20 at 19:27
6

I tried to use the AsyncStorage from the java layer. But, I couldn't. So, I built a React Native plugin to access Android's Native SharedPreferences from the javascript layer. I have published it in the github (https://github.com/sriraman/react-native-shared-preferences)

Now I'm using this SharedPreferences from both Java and React Native layer.

Sriraman
  • 7,658
  • 4
  • 40
  • 60
1

My solution is to use directly the ReactDatabaseSupplier class (my app doesn't use Rocksdb so I can be quite sure that the SQLite DB is always used as storage (and, I guess it will always prefer the SQLite database over local storage))

The database is a simple key-value DB (two columns, key and value), with a table name 'catalystLocalStorage' (you can try to read the ReactDatabaseSupplier#TABLE_NAME but it's protected, you can try using reflection, but I'm not sure it's worth the troubles)

Cursor catalystLocalStorage = null;
SQLiteDatabase readableDatabase = null;

try {
  readableDatabase = ReactDatabaseSupplier.getInstance(this.getApplicationContext()).getReadableDatabase();
  catalystLocalStorage = readableDatabase.query("catalystLocalStorage", new String[]{"value"}, "key = ?", new String[] { "keyName" }, null, null, null);
  final String value = catalystLocalStorage.getString(catalystLocalStorage.getColumnIndex("value"));
  [...]
} finally { 
  if (catalystLocalStorage != null) {
    catalystLocalStorage.close();
  }

  if (readableDatabase != null) {
    readableDatabase.close();
  }
}

It works to me, not sure how future-proof it can be

Marco Acierno
  • 14,682
  • 8
  • 43
  • 53
1

Use react-native-default-preference. Its way better than react-native-shared-preferences.

0

Yes you can. React native You need to create method in React native where you return values. Native Use PackagesModule Class Provided by facebook for access React-native method from Native using this can able to access AsyncStorage

Android Native Modules

Penny Liu
  • 15,447
  • 5
  • 79
  • 98