Get value from firestore collection in react native - react-native

I want to write a function that will get the value for the collection, as shown in the picture:
And here is my code, I really don't know what to do after the "then()":
const getLocation = () => {
firebase
.firestore()
.collection("users")
.doc(currentUser.uid)
.get()
.then((querySnapshot) => {});
};
Note that currentUser is redux, meaning that the query will execute only for the current user that is logged in

If you want to return the value of businessLocation only you can do this:
const getLocation = () => {
return firebase.firestore()
.collection("users")
.doc(currentUser.uid)
.get()
.then(function(doc) {
if (doc.exists) {
data = doc.data();
return data.businessDetails.businessLocation;
} else {
return "";
}
});
};
You can get more information on how to get data in firestore at the Official Documentation.
Note: This makes your function become an asynchronous function. Therefore you should call it as follows:
getLocation().then(result => {
//Do whatever you want with the result value
console.log(result);
})

Related

React-Native Async Storage returns weird object with correct value in two consecutive lines

I've researched this and not found a similar case answered, at my whits end.
I have the following code to get an item from AsyncStorage, which returns the correct value when I log it on the console, but the function's return value is: {\"_40\":0,\"_65\":1,\"_55\":\"Nick\",\"_72\":null}
const getData = async () => {
try {
const value = await AsyncStorage.getItem('userDetails');
if(value !== null) {
const wsi_user = await JSON.parse(value);
console.log("userName: " + wsi_user.userName); // returns "Nick"
return wsi_user.userName; // returns {\"_40\":0,\"_65\":1,\"_55\":\"Nick\",\"_72\":null}
}
} catch(e) {
letter = "D";
}
}
I've seen similar articles where people mention that the promise needs to resolve and I get that, but my result is within the outputted weird object, AND, my result is correct when logged to console the line before return.
Please advise. No clue how to fix this.
You can call this function like:
const result = await getData()
Also, you don't need the await before JSON.parse() as it is synchronous.
Maybe you can use react-native-easy-app, through which you can access AsyncStorage synchronously, and can also store and retrieve objects, strings or Boolean data
import { XStorage } from 'react-native-easy-app';
import { AsyncStorage } from 'react-native';
// or import AsyncStorage from '#react-native-community/async-storage';
export const RNStorage = { userInfo: undefined };
const initCallback = () => {
// From now on, you can write or read the variables in RNStorage synchronously
// equal to [ await AsyncStorage.setItem('userInfo',JSON.stringify({ name:'rufeng', age:30})) ]
RNStorage.userInfo = {name: 'rufeng', age: 30};
};
XStorage.initStorage(RNStorage, AsyncStorage, initCallback);
You need to convert the object to a string before saving it in the async storage AsyncStorage.setItem(key, JSON.stringify(data));
Example:
export const setStorageItem = async (key: string, data: any): Promise<void> => {
return AsyncStorage.setItem(key, JSON.stringify(data));
};
export const getStorageItem = async <T>(key: string): Promise<T | null> => {
const item = await AsyncStorage.getItem(key);
if (item) {
return JSON.parse(item);
}
return null;
};
Example from the docs

React Native AsyncStorage: using await and async

I'm trying to get all keys from my AsyncStorage database and then filter them in another function, can't seem to get it to wait until AsyncStorage has returned the data?
This function returns the keys in an array:
DATABASE_getAllCoffeeEntries = () => {
AsyncStorage.getAllKeys((err, keys) => {})
.then(keys => {
AsyncStorage.multiGet(keys, (error, items) => {
return items;
}).then(items => {
return items; // array of items is returned
});
});
}
and this function is meant to call the function above then wait for the result then filter down the data.
somefunc = async () => {
var items = await DATABASE_getAllCoffeeEntries();
var someItems = items.filter(function (result, i, item) {
// do filtering stuff
return item;
});
// do something with filtered items
}
Have tried a lot on here but can't get my head around it... any help would be great, thanks.
You need to actually return something from your DATABASE_getAllCoffeeEntries
You could do something like this.
First we wrap your call inside a promise. Which will resolve if we get all the items from AsyncStorage or reject if there is a problem.
Make sure that our calls to AsyncStorage are inside a try/catch. await calls can throw so we need to make sure that we handle any errors.
Use async/await when getting the items from AsyncStorage as this gets ride of the callbacks that are trapping the responses from AsyncStorage. It also can make your code easier to read
Here is the refactor
DATABASE_getAllCoffeeEntries = () => {
return new Promise( async (resolve, reject) => {
try {
let keys = await AsyncStorage.getAllKeys();
let items = await AsyncStorage.multiGet(keys)
resolve(items)
} catch (error) {
reject(new Error('Error getting items from AsyncStorage: ' + error.message))
}
});
}
Then we can call the function like this, though we will have to wrap it in a try/catch as it can throw.
somefunc = async () => {
try {
var items = await this.DATABASE_getAllCoffeeEntries();
var someItems = items.filter(function (result, i, item) {
// do filtering stuff
return item;
});
// do something with filtered items
} catch (error) {
// do something with your error
}
}

how to get multiple fields from expo SecureStore

I am new to ES6 and react-native, trying to get multiple values from the SecureStore.
I think I am misunderstanding promises here ... global.userData is empty in the Promise.all(promises).then function. The relevant values do exist in the secure store
My code is:-
getUserData(fields) {
var promises = [];
var that = this;
global.userData = {};
function getField(field) {
return SecureStore.getItemAsync(field)
.then(res => {
console.log(field+"="+res); // this appears after the log below
global.userData[field] = res;
})
.catch(error => {
global.userData[field] = null;
});
}
fields.map(field => {
promises.push[getField(field)];
});
Promise.all(promises).then(function(v) {
console.log(global.userData); // this is empty
that.setState({ isReady: true }); // allow page to render
});
}
getUserData(["userId", "userName","etc"]);
My bad ... inadvertantly used
promises.push[getField(field)];
should have been:
promises.push(getField(field));
Suprised it wasn't detected as a syntax error ...

Get item from AsyncStorage in React Native

I have a list of companies in React Native.
When I click on one of those companies I get the url of the API that is used for selected company. Then I store it to AsyncStorage and then I show the login screen. The function is as follows:
selectCompany(data_url, e) {
AsyncStorage.setItem("data_url", JSON.stringify(data_url), () => this.props.login());
}
Then on login page if I click on sign in button I go to the onLogin function, the function is as follows:
onLogin: function() {
fetch(data.url + '/manager/api/v1/obtain-auth-token/', })
.then(function(body) {
return body.json();
}).then(function(json) {
.....
}).catch(function() {
....
});
},
And data.url comes from data.js file, and I try to get url from the data.js file as follows:
let data_url = AsyncStorage.getItem("data_url").then(json => JSON.parse(json));
module.exports = {
url: data_url,
.....
}
But it doesn't work. Any advice?
AsyncStorage is async, therefore data_url will not be defined until it's retrieved what its looking for, you would need to move the fetch into the promise thats returned from the get so it will run it once it's done getting the data. This might be one way you tackle it:
const data_url = () => AsyncStorage.getItem("data_url"); //change this into a function
module.exports = {
url: data_url,
.....
}
now inside your component...
onLogin: function() {
data.url().then((url) => {
fetch(JSON.parse(url) + '/manager/api/v1/obtain-auth-token/', })
.then(function(body) {
return body.json();
}).then(function(json) {
.....
}).catch(function() {
....
});
});
},
AsyncStorage.getItem is a promise and needs to await for response rather than accessing direct and the function calling it should be defined as async. Here is an example to retrieve from AsyncStorage..
export async function getAccessKey(){
let accessToken = await AsyncStorage.getItem(ACCESS_TOKEN);
return accessToken;
}

React Native - How to see what's stored in AsyncStorage?

I save some items to AsyncStorage in React Native and I am using chrome debugger and iOS simulator.
Without react native, using regular web development localStorage, I was able to see the stored localStorage items under Chrome Debugger > Resources > Local Storage
Any idea how can I view the React Native AsyncStorage stored items?
React Native Debugger has this built in.
Just call showAsyncStorageContentInDev() in the RND console and you'll be able to see a dump of your app's storage.
You can use reactotron i think it has Async Storage explorer ;)
https://github.com/infinitered/reactotron
Following should work,
AsyncStorage.getAllKeys((err, keys) => {
AsyncStorage.multiGet(keys, (error, stores) => {
stores.map((result, i, store) => {
console.log({ [store[i][0]]: store[i][1] });
return true;
});
});
});
I have created a helper method to log all Storage in a single object (more clean to log for example in Reactotron):
import AsyncStorage from '#react-native-community/async-storage';
export function logCurrentStorage() {
AsyncStorage.getAllKeys().then((keyArray) => {
AsyncStorage.multiGet(keyArray).then((keyValArray) => {
let myStorage: any = {};
for (let keyVal of keyValArray) {
myStorage[keyVal[0]] = keyVal[1]
}
console.log('CURRENT STORAGE: ', myStorage);
})
});
}
react native debugger
right click on free space
With bluebird you can do this:
const dumpRaw = () => {
return AsyncStorage.getAllKeys().then(keys => {
return Promise.reduce(keys, (result, key) => {
return AsyncStorage.getItem(key).then(value => {
result[key] = value;
return result;
});
}, {});
});
};
dumpRaw().then(data => console.log(data));
Maybe late, but none of these solutions fit for me.
On android, with Android Studio open file explorer then go to data/data/your_package_name
Inside you should have a folder called database and inside a file RKStorage.
This file is a SQLite3 file so get your favorite SQLite explorer and explore. If you want one this one does the job : DB Browser for SQLite
I did not find Reactotron to have any type of pretty printing enabled and it's also brutally latent so I just wrote a simple function using lodash. You could use underscore too.
Assuming you have a static mapping of all your keys...
const keys = {
key1: 'key1',
key2: 'key2'
}
export function printLocalStorage() {
_.forEach(keys, (k, v) => {
localStore.getAllDataForKey(v).then(tree => {
console.log(k) // Logs key above the object
console.log(tree) // Logs a pretty printed JSON object
})
})
}
It's not performant but it solves the problem.
You can Define function to get all keys by using async and await
getAllkeys = () => {
return new Promise( async (resolve, reject) => {
try {
let keys = await AsyncStorage.getAllKeys();
let items = await AsyncStorage.multiGet(keys)
resolve(items)
} catch (error) {
reject(new Error('Error getting items from AsyncStorage: ' + error.message))
}
});
}
somefunc = async () => {
try {
var items = await getAllkeys();
var someItems = items.filter(function (result, i, item) {
// do filtering stuff
return item;
});
// do something with filtered items
} catch (error) {
// do something with your error
}
}
I have a expo snack that shows this and also performs a "load". So it is useful for doing a dump of the contents and storing it to a file and loading it up later.
Here are they parts.
const keys = await AsyncStorage.getAllKeys();
const stores = await AsyncStorage.multiGet(keys);
const data = stores.reduce(
(acc, row) => ({ ...acc, [row[0]]: row[1] }),
{}
);
// data now contains a JSONable Javascript object that contains all the data
This ammends the data in the AsyncStorage from a JSON string.
// sample is a JSON string
const data = JSON.parse(sample);
const keyValuePairs = Object.entries(data)
.map(([key, value]) => [key, value])
.reduce((acc, row) => [...acc, row], []);
await AsyncStorage.multiSet(keyValuePairs);
import AsyncStorage from "#react-native-async-storage/async-storage";
export const printAsyncStorage = () => {
AsyncStorage.getAllKeys((err, keys) => {
AsyncStorage.multiGet(keys, (error, stores) => {
let asyncStorage = {}
stores.map((result, i, store) => {
asyncStorage[store[i][0]] = store[i][1]
});
console.table(asyncStorage)
});
});
};
enter image description here