我正在开发一个应用程序,我们需要在用户设备上对脱机AppSync缓存进行加密。我正在尝试使用内置的“ offlineConfig.storage”来包装加密的领域数据库,但是我遇到了一些重大挑战。
首先,我们不在此应用程序中使用Redux,因此大多数在线示例都浮在表面。
第二,当我尝试向客户端发出请求时(例如client.query({query ...}),该请求再也不会从异步/承诺中返回。
我实现了一个类,该类提供必需的setItem / getItem / removeItem函数,但只有一个在未记录的“ getAllKeys”函数中被调用的类。
客户端设置
import AWSAppSyncClient, { AUTH_TYPE } from 'aws-appsync';
import config from '../utils/configFile';
import storage from './storage.js'
const client = new AWSAppSyncClient({
url: config.AppSyncEndPoint,
region: config.Region,
auth: {
type: AUTH_TYPE.API_KEY,
apiKey: config.AppSyncAPIKey,
},
disableOffline: false,
offlineConfig: {
storage: storage
}
});
存储接口对象
import Realm from 'realm';
const ITEM_SCHEMA = {
name: "offlineStorage",
primaryKey: "name",
properties: {
name: "string",
content: "string"
}
}
const REALM_PATH = 'tealpanda.realm';
class offlineStorage {
constructor() {
console.log(`Constructing`);
this.realm = createRealmAccess();
}
accessItemInstances = async () => {
console.log(`Accessing realm`);
const realm = await this.realm();
return realm.objects(ITEM_SCHEMA.name);
}
getItem = async (key) => {
console.log(`getItem(${key})`);
const items = await this.accessItemInstances();
const matches = items.filtered((name = `${key}`));
if (matches.length > 0 && matches[0]) {
return matches[0].content;
} else {
throw new Error(`Could not get item with key: '${key}'`);
}
}
setItem = async (key, value) => {
console.log(`setItem(${key}, ${value})`);
const realm = await this.realm();
realm.write(() => {
realm.open(
ITEM_SCHEMA.name,
{
name: key,
content: value
},
true
);
});
}
removeItem = async (key) => {
console.log(`removeItem(${key})`);
const realm = await this.realm();
const items = await this.accessItemInstances();
realm.write(() => {
const item = items.filtered((name = `${key}`));
realm.delete(item);
});
}
getAllKeys = async (callback) => {
try{
console.log(`Getting stored state...`);
const items = await this.accessItemInstances();
let keys = items.map(item => (item.name));
console.log(`Keys: ${keys}`);
return keys;
} catch (e) {
console.error(e);
callback && callback(e);
}
}
}
export default new offlineStorage();
function createRealmAccess(path = REALM_PATH) {
let __realm = null;
return async function accessRealm() {
if (!__realm) {
try {
__realm = await Realm.open({
schema: [ITEM_SCHEMA],
path
});
} catch (error) {
throw error;
}
}
return __realm;
};
}
调用功能:
export const write = async (key, value) => {
console.log('Writing ' + key)
const result = await readSetting(key);
console.log(result);
if (result.data.listSettings.items.length) {
const setting = result.data.listSettings.items[0];
console.log(`Updating ${key}: ${value.toString()}`)
return await client.mutate({ mutation: gql(mutations.updateSettings), variables: { input: { id:setting.id, value}}});
} else {
createSetting(key, value);
}
return true;
}
我希望对client.mutate(...)的调用能够持久保存到领域数据库并更新DynamoDB(通过GraphQL API)-但它永远不会调用存储对象上的setItem函数-也不是通过AppSync持久化。
如果我禁用脱机存储,它将按预期工作;并且如果我启用了脱机存储,但未指定自定义存储,它将按预期工作(通过AppSync保持脱机状态)。