Как правильно читать AsyncStorage на Android

Похоже, что возможен доступ к AsyncStorage из Android (родной); но я все еще изо всех сил пытаюсь заставить эту работу.

В моем приложении React Native у меня есть что-то вроде:

Магазин

const config = {
  ...
}

export const reducers = {
  ...
  user: user
}


let rootReducer = combineReducers(reducers)
let reducer = persistReducer(config, rootReducer)

User Reducer

export class Actions {
    ...
}

const initialState = {
      first_name: : null,
      last_name: : null,
      email: null,
      addresses: [
          { ... }
      ]
    }
  }
}

export const reducer = (state = initialState, action) => {
  switch (action.type) {
    ...
  }
}

Получение пользователя из магазина

const user = store.getState().user
console.log(user.first_name) // Steve
...

Теперь проблема начинается, когда я пытаюсь получить того же пользователя с Android, из всех моих неудачных попыток это то, что у меня есть:

try {
    readableDatabase = ReactDatabaseSupplier.getInstance(getReactApplicationContext()).getReadableDatabase();
    catalystLocalStorage = readableDatabase.query("catalystLocalStorage", new String[]{"value"}, "key = ?", new String[] { "full_name" }, null, null, null);
    String[] names = catalystLocalStorage.getColumnNames();
    if (catalystLocalStorage.moveToFirst()) {
        final String value = catalystLocalStorage.getString(catalystLocalStorage.getColumnIndex("value"));
        Log.d(TAG, value);
    }
} finally {
    if (catalystLocalStorage != null) {
        catalystLocalStorage.close();
    }

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

Поскольку User это объект, я не знаю, правильный ли это способ получить 'first_name', я пытался получить 'user', но не сработало.

Я начинаю думать, что мне следует использовать response-native-sqlite-storage где я мог бы узнать свою структуру данных, но я не знаю, смогу ли я получить доступ к этой базе данных на Android.

PS: Мне нужен доступ AsyncStorage, а не SharedPreferences


Версии Lib

react-native: 0.48.4
redux: 3.7.2
redux-persist: 5.4.0

Некоторые вопросы, которые не помогли


person Pablo    schedule 08.01.2018    source источник


Ответы (2)


AsyncStorage это уникальный объект JSON, и вместо этого я ожидал много строк с key и value; Вот почему я получал ноль.

Итак, сначала я продолжу запрос

catalystLocalStorage = readableDatabase.query("catalystLocalStorage", new String[]{"key", "value"}, null, null, null, null, null);

затем я проверяю, чтобы избежать нулевого указателя

if (catalystLocalStorage.moveToFirst()) {

тогда я делаю выборку

do {
    // JSONObject will ask for try catch
    JSONObject obj = new JSONObject(catalystLocalStorage.getString(catalystLocalStorage.getColumnIndex("value")));
} while(catalystLocalStorage.moveToNext());

Я уверен, что у этого есть способы сделать это получше, но знаю, что меня это устраивает.

Если у вас есть идеи получше, оставьте их.

ОБНОВЛЕНИЕ

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.modules.storage.ReactDatabaseSupplier;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.ArrayList;

public class AsyncStorage {

    public static String TAG = "RNAsyncStorage";
    public ReactApplicationContext context;
    public ArrayList<JSONObject> collection;
    public JSONObject data;
    public JSONObject user;

    Cursor catalystLocalStorage = null;
    SQLiteDatabase readableDatabase = null;

    public AsyncStorage (ReactApplicationContext context) {
        this.context = context;
        this.collection = new ArrayList<JSONObject>();
        this.fetch();
        this.setUser();
    }

    public void fetch() {
        try {
            readableDatabase = ReactDatabaseSupplier.getInstance(context).getReadableDatabase();
            catalystLocalStorage = readableDatabase.query("catalystLocalStorage", new String[]{"key", "value"}, null, null, null, null, null);

            if (catalystLocalStorage.moveToFirst()) {
                do {
                    try {
                        // one row with all AsyncStorage: { "user": { ... }, ... }
                        String json = catalystLocalStorage.getString(catalystLocalStorage.getColumnIndex("value"));
                        JSONObject obj = new JSONObject(json);

                        String user = obj.getString("user");

                        JSONObject res = new JSONObject();
                        res.put("user", new JSONObject(user));

                        collection.add(res);
                    } catch(Exception e) {
                        // do something
                    }
                } while(catalystLocalStorage.moveToNext());
            }
        } finally {
            if (catalystLocalStorage != null) {
                catalystLocalStorage.close();
            }

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

            data = this.collection.get(0);
        }
    }

    public String getFullname () {
        try {
            return user.getString("fullname");
        } catch (Exception e) {
            return "";
        }
    }
}

Вызов класса

AsyncStorage as = new AsyncStorage(context);
as.getFullname()
person Pablo    schedule 09.01.2018
comment
Получить контекст приложения реакции в любом месте приложения непросто. Вы можете мне помочь, как вы получили контекст приложения React? - person Tarun; 21.01.2020
comment
@ Тарун, извини, но я не эксперт, поэтому мне нужно посмотреть, что я сделал, чтобы помочь тебе с этим. Но с тех пор, как я переехал, я работаю в другой компании, и у меня нет оригинального проекта. - person Pablo; 21.01.2020
comment
@Tarun У меня такая же проблема, вы смогли ее решить? - person Amogh Jahagirdar; 30.05.2020

У меня была проблема с будильником в моем приложении, и я решил использовать AsyncStorage на стороне Android, затем я использую приведенный ниже код, и я могу получить все значения из AsyncStorage и сгенерировать все аварийные сигналы, которые были зарегистрированы в AsyncStorage моего приложения.

SQLiteDatabase readableDatabase = null;
        readableDatabase = ReactDatabaseSupplier.getInstance(this.reactContext).getReadableDatabase();
        Cursor catalystLocalStorage = readableDatabase.query("catalystLocalStorage", null, null, null, null, null, null);
        try {
            List<AlarmeDTO> listaAlarmes = new ArrayList<>();
            if (catalystLocalStorage.moveToFirst()) {

                do {
                    //Ex: key: 01082019_0800
                    //value: [{executionDate: 2019-08-01T08:00}]
                    String key = catalystLocalStorage.getString(0);
                    String json = catalystLocalStorage.getString(1);

                    if (dados.length == 3) {
                        ...generate my alarms with key and json
                    }

                } while (catalystLocalStorage.moveToNext());

            }//2_31082019_0900 - [{"idPrescricaoMedicamento":35,"nomeMedicamento":"VITAMINA"}]

        } finally {
            if (catalystLocalStorage != null) {
                catalystLocalStorage.close();
            }

            if (readableDatabase != null) {
                readableDatabase.close();
            }
        }
person Wallace Rodrigo Nascimento Sou    schedule 03.09.2019
comment
Мне пришлось сделать небольшую корректировку, потому что я использовал это в MainActivity.java, вместо getInstance(this.reactContext) мне пришлось использовать getInstance(getApplicationContext()). Спасибо, этот код очень помог начать работу. - person hmajid2301; 11.01.2020