React Native's version of localstorage is AsyncStorage, it would be great if it was supported out of the box. I spent some time trying to add it to getStorage() but I eventually ran out of time and found a possible workaround that I could do in my app code instead. My findings/potential challenges:
AsyncStorage has the same method names for setting/getting (getItem, etc) as localstorage, which is good, but it is async (no shit Sherlock!) and returns a promise. So it can't be called the same way as localstorage. To unify access to all storages, the localhost and FakeStorage method return values should probably be resolved into promises as well.
AsyncStorage is part of react-native npm package, which is quite big. It would be nice if horizon didn't have to explicitly depend on react-native but just use AsyncStorage if the main app has it installed, but not 100% sure how to do that.
The following app code relies on the FakeStorage mechanism in Horizon and uses AsyncStorage to persist the storage in the app.
Btw. Horizon.clearAuthTokens() does not seem to work (see code comment below), not sure if it is broken with FakeStorage or if it's something with RN.
import React, { Component } from 'react';
import { AsyncStorage } from 'react-native';
import Horizon from '@horizon/client';
const horizonOptions = {
host: 'localhost:8181',
};
let horizon;
export class Machine extends Component {
state = {
currentUser: null,
authEndpoint: '',
};
signOut = () => {
AsyncStorage.removeItem('horizon-jwt').then(() => {
// Horizon.clearAuthTokens(); is not working in RN so using connect
// without token to get the same behavior.
this.connect();
});
}
signIn = (horizonToken) => {
if (! horizonToken || this.state.currentUser) {
return;
}
AsyncStorage.setItem('horizon-jwt', horizonToken);
this.connect(horizonToken);
};
// Custom methods
connect(horizonToken = undefined) {
// Options
let options = Object.assign({}, horizonOptions);
if (horizonToken) {
options.authType = {'token': horizonToken};
}
horizon = Horizon(options);
horizon.status(e => {
console.log('status', e);
});
horizon.onSocketError(e => {
console.log('socketError', e);
});
// Get the OAuth endpoint
horizon.authEndpoint('auth0').subscribe(endpoint => {
this.setState({authEndpoint: endpoint});
});
// Check if user is logged in
if (horizon.hasAuthToken()) {
horizon.currentUser().fetch().subscribe(user => {
this.setState({currentUser: user});
});
} else {
this.setState({currentUser: null});
}
}
// Lifecycle methods
componentDidMount() {
AsyncStorage.getItem('horizon-jwt').then(horizonToken => {
this.connect(horizonToken);
});
}
render() {
return; //
}
}
Server version: 2.0.0 Client version: 2.0.0
React Native's version of localstorage is AsyncStorage, it would be great if it was supported out of the box. I spent some time trying to add it to getStorage() but I eventually ran out of time and found a possible workaround that I could do in my app code instead. My findings/potential challenges:
The following app code relies on the FakeStorage mechanism in Horizon and uses AsyncStorage to persist the storage in the app.
Btw.
Horizon.clearAuthTokens()
does not seem to work (see code comment below), not sure if it is broken with FakeStorage or if it's something with RN.