Hello I'm new at react native and im building a simple app that is saving an array and a value with asyncStorage, but after i build the app using Expo the data persists and is saved on the apk.
How can I wipe the data on installation (a little bit inefficient, but for now it would do it becouse I just will probably have a couple of elements on the array) or on build (I dont know if it is possible) or other way...
That's how i am saving the data.
const storeData = async (array) => {
try {
console.log("STORED");
const jsonValue = JSON.stringify(array);
await AsyncStorage.setItem("#sleep_data", jsonValue);
} catch (e) {
console.log("error saving")
}
};
AsyncStorage saved data on your device only. To clear the storage call this from your app:
const clearStorage = () => AsyncStorage.clear()
Related
I'm building a complete pokedex app using react-native/expo with all 900+ Pokémon.
I've tried what seems like countless ways of fetching the data from the API, but it's really slow.
Not sure if it's my code or the sheer amount of data:
export const getAllPokemon = async (offset: number) => {
const data = await fetch(
`https://pokeapi.co/api/v2/pokemon?limit=10&offset=${offset}`
);
const json = await data.json();
const pokemonURLS: PokemonURLS[] = json.results;
const monData: PokemonType[] = await Promise.all(
pokemonURLS.map(async (p, index: number) => {
const response = await fetch(p.url);
const data: PokemonDetails = await response.json();
const speciesResponse = await fetch(data.species.url);
const speciesData: SpeciesInfo = await speciesResponse.json();
return {
name: data.name,
id: data.id,
image: `https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/${data.id}.png`,
description: speciesData.flavor_text_entries,
varieties: speciesData.varieties,
color: speciesData.color.name,
types: data.types,
abilities: data.abilities,
};
})
);
Then I'm using it with a useEffect that increases offset by 10 each time and concats the arrays, until offset > 900.
However like I said, it's really slow.
Should I be saving this data locally to speed things up a little?
And how would I go about it? Should I use local storage or save an actual file somewhere in my project folder with the data?
The biggest performance issue I can see is the multiple fetches you perform as you loop though each pokemon.
I'm guessing that the data returned by the two nested fetches (response and speciesResponse) is reference data and are potentially the same for multiple pokemon. If this is the case, and you can't change the api, then two options pop to mind:
Load the reference data only when needed ie. when a user clicks on a pokemon to view details.
or
Get ALL the reference data before the pokemon data and either combine it with your pokemon fetch results or store it locally and reference it as needed. The first way can be achieved using local state - just keep it long enough to merge the relevant data with the pokemon data. The second will need application state like redux or browser storage (see localStorage or indexeddb).
I have a to-do list that works like trello, with lists and draggable cards. I have the app functioning with both saving the state of the cards to mongoDB and localstorage using JSON. What I don't understand is how I am supposed to be constantly updating mongoDB every time I move or edit a card. It seems there must be a different way. Just for reference - this is the function I am using to update the DB entry. It saves and renders, but it feels wrong to be doing this with each state change.
async function mainUpdate(data) {
const uri =
'mongodb+srv://xxxxxxxxxxxxxxxxxx.mongodb.net/test';
const client = new MongoClient(uri);
try {
await client.connect();
await updateListingByName(client, 'user-jeff', { cachedState: data });
} finally {
await client.close();
}
}
I tried it with this method
useEffect(() => {
async function getUserData() {
var userData = await firebase.firestore().doc("ingredients/" + user.uid).get();
var labels = []
userData.data().ingredients.forEach(ingredient => {
labels.push(ingredient.label)
})
setUserIngredients(labels)
setUserRecipes(userData.data().recipes)
}
getUserData()
fetchRecipes(userIngredients)
}, [])
but it does not load when I use the app I need to save the file on my computer before it fetches the data. I'm using expo to debug the app on my smartphone. I want it to fetch the data when I go to the screen or when my app is starting
You can use loader when data is being fetching and hide it when data is fetched !
also if you want instant data fetch even before rendering screen ,then it is not the good approach if you really want it then do data fetch in custom constructor!
i.e
const [constructorHasRun, setConstructorHasRun] = useState(false);
and call fetch API in this constructor
const constructor = () => {
if (constructorHasRun) return;
// fetch API
setConstructorHasRun(true);
};
Hope You wants it and helped !
For these cases, I recommend saving data in Redux states is helping your app seems fast and you can access it when you need it.
Also, if you don't use Redux, you can save your data in SQLite because it seems your data about recipes, and update your data in the splash screen.
That's just another solution...
We recently launched an application for a company that provides staff for music festivals using vue.js and a firebase realtime database. We have about 2,000 users and currently 8 events that they can apply for. Each user has profiles and admins can manage their events and hires from the app. The app fires up right away, but the data in "getInitialUserState" takes a long time to populate. I'm worried that once we have 5K or 10K users, load time will only get worse.
In our App.vue file:
created () {
this.$store.dispatch("getInitialState")
this.$store.dispatch("getInitialEventsState")
}
Then in Users.vue:
created () {
this.$store.dispatch("getInitialUserState")
}
In our store:
getInitialState({ commit }) {
firebase.auth().onAuthStateChanged(function(user) {
console.log(user);
const db = firebase.database();
db.ref('users/').child(user.uid).on('value', (snap)=>{
let u = snap.val();
u.id = user.uid
commit('setUser', u);
})
})
},
getInitialUserState({commit}, payload){
const db = firebase.database()
db.ref("users").once("value", (snap) => {
let data = []
for(var key in snap.val()){
let user = snap.val()[key]
user.id = key
data.push(user)
}
commit('setUsers', data)
commit('setUsersMap', snap.val());
})
},
and:
getInitialEventsState({ commit }) {
let db = firebase.database();
db.ref("/events").on("value", function (snapshot) {
let data = []
for (var key in snapshot.val()) {
let event = snapshot.val()[key];
if(event.title){
event.id = key
data.push(event)
}
}
commit("setLoadedEvents", data)
commit("setEventsMap", snapshot.val());
})
}
We've tried adding v-cloak to different elements so don't render without all of the correct data, but that either doesn't work or we are doing it wrong. I've also tried loading data at different lifecycle hooks, but that doesn't make any difference either.
What I want to happen is for my data (as a logged-in user) and for event data to load immediately. Then, EITHER for the "Users" data to only load if the user in a admin (so it won't slow down the experience for regular users), or for Users data to load asynchronously and without interfering with the rest of the app. Currently, while the Users data is loading, the page is effectively frozen and you can't click to go to any other pages.
Firebase should be fast. We are using firebase hosting as well. I'm hoping you guys can at least point us in the right direction.
What is the correct way to load data from thousands of users without slowing down the user experience?
Thanks!
I want to make a function to reset all the content and initialize my webapp. Since I have a couple of generated names databases I would like just to remove them all.
Is there a way to do something like PouchDB.destroyAll() ?
It's not possible using PouchDB directly but you can do it using the following snippet:
indexedDB.webkitGetDatabaseNames().onsuccess = (e) => {
for(let i = 0; i < e.target.result.length; i++){
let db = e.target.result[i];
if(db.startsWith('_pouch_')){
indexedDB.deleteDatabase(db);
}
}
};
This assumes that you're using PouchDB with indexedDB in chrome. If this is not the case, you'll have to adapt the above code to work with whatever storage engine and browser/server you're using.
I recommend doing it the pouchy way by using the PouchDB allDbs() plugin because it works when different db adapters have been used.
For example
try {
const dbs = PouchDB.allDbs();
// dbs is an array of strings, e.g. ['mydb1', 'mydb2']
// delete the databases by name or whatever.
} catch(err) {
}
The destroy() method is handy, see Destroying a database
From a developer perspective, see Deleting your local database
The IndexedDB: webkitGetDatabaseNames is removed from chrome
see -> https://www.chromestatus.com/feature/5725741740195840
Agree that isn't possible using PouchDB directly you can do it using the following.
export const deletePouchDB = async() =>{
const dbs = await window.indexedDB.databases();
dbs.forEach(db => {
if (db.name.includes('_pouch_')) {
window.indexedDB.deleteDatabase(db.name);
}
});
};