how do I display firestore data with React - reactjs

I am trying to render my firestore data to my web app using React.
here is my code
I can see the document ID when I console.log(posts.id), however I cannot find the content of that document.
Here are the content of a document

The method for getting the data is .data, as in:
console.log(posts[0].data())
To render something for each post might be something like:
<p>
{posts.map(doc => {
const data = doc.data();
return (
<div>{data.title}</div>
)
})}
</p>
Personally, unless i need something other than the data from the document, i tend to do my calls to .data() before i even put it into react state. That way i don't need to do it on each render. e.g:
useEffect(() => {
database.posts.get().then(snapshot => {
setPosts(snapshot.docs.map(doc => doc.data());
});
});

Related

Can anyone explain.Why the 'res" is getting logged two times?

I am trying to get the images data from flickr. I am getting the response but not able to display the image.I have tried using useEffect to fetch the api and useState variable to store images array. Still it was getting called two times.
const DisplayImages = () => {
let photos = [];
fetch(
` https://www.flickr.com/services/rest/?method=flickr.galleries.getPhotos&api_key=***********************&gallery_id=************&format=json&nojsoncallback=1`
)
.then((response) => response.json())
.then((res) => {
const images = res;
console.log(res);
photos = images.photos.photo;
});
return (
<>
<div className="imagescontainer">
{photos.map((photo) => {
console.log(photo);
let url = `https://farm${photo.farm}.staticflickr.com/${photo.server}/${photo.id}_${photo.secret}`;
<>
{/* <img src={require(url)} alt="img" /> */}
</>
})}
</div>
</>
);
};
I expected the images to be rendered.
It's getting called twice because React is probably configured to be in strict mode in development, which causes hooks to be called twice.
Second, you're using a locally-scoped variable photos to hold state, when you need to use useState instance, otherwise React won't know when the state changes and re-render the component.
Third, it looks like you're setting photos, which is initialized with an empty array, to a single instance of a photo.

React native Firebase Firestore query

I'm trying to display a user's order history using query. The users' orders, dubbed "items", is an array and I can see the array being logged in the console with my code below. But nothing is being displayed in the app. What am I missing? Also attached my Firestore db for reference.
const q = query(ordersCollectionRef, where("items", "==", "userId"));
onSnapshot(q, (snapshot) => {
let orders = [];
snapshot.docs.forEach((doc) => {
orders.push({ ...doc.data(), id: doc.id });
});
console.log(orders);
});
...and in the return:
{orders.map((order) => {
if (order.id === currentUser.uid) {
return (
<View>
<Text>test{orders.items}</Text>
</View>
);
};
})}
For React to properly "understand" that you have updated data in a state variable, you need to use the "set state function" and NOT update the state variable directly.
In your code, put the data into a new and temporary variable, the after the forEach() call: setOrders(theTempVariable)
That puts the data in theTempVariable into the orders variable and it tells React that the variable has a new value....so React will "react" to state changing and it will re-render your component.

how to save the data from firebase I recently Created with axios and react?

I am kinda new into react and web dev overall, I want to ask, where is the issue in my proble?
I created a database with firebase, posting into it went fine, but now I am trying to GET the date I posted before and store it Into a variable, so then I can iterate through the data and map different components for each data. I am using axios, here is the code:
function CreateBlog(props) {
const [fetchedData, setFetchedData] = useState();
useEffect(() => {
axios.get("https://diary-page-default-rtdb.firebaseio.com/diaryPages.json")
.then((response) => {
console.log(response.data);
setFetchedData(response.data);
console.log(fetchedData)
})
.catch(error => console.log("error occured:", error))
}, []);
so as I console.log the response.data I get the object with the data stored in the database, but when I setFetchData and console.log the fechedData I get undefined. Is there any simple way to store the data inside "fetchedData" as an array where every different object represents a part of the array so that later on I can map through the array and display the data in separate components?
You are storing the data correctly, but you are not able to console.log them straight away because the useState operates asynchronously.
If you want to console.log your fetchedData, have a useEffect listening to changes on that state (for demonstration purposes):
useEffect(() => {
console.log(fetchedData)
}, [fetchedData]);
A further suggestion I would give (not essential though), is to set your initial state as an empty array since that's the type of data you are storing:
const [fetchedData, setFetchedData] = useState([]);
From here, you can map through your data as such:
{fetchedData?.map((data, index) => <div key={index}>{data}</div>}
Just make sure data is not an object if you copy my example, or it will return you an error since you can't display objects inside jsx

React Redux FireStore - Changes in FireStore collection does not reflect on my screen unless I refresh

I use React with Redux and Firebase. Here is one of the functions from my Action.js
export const loadItemsInCategory = (categoryId) => {
return (dispatch) => {
let itemsArray = [];
firestoreService.getItemsInCategory(categoryId)
.then(updatedGroceryList => {
itemsArray = updatedGroceryList;
console.log(`category id is ${categoryId}`)
dispatch(loadItemsInCategoryHelper(categoryId, itemsArray))
})
.catch((error) => console.log(error));
}
}
It's a normal FireStore query. Here is what happens in firestoreService.getItemsInCategory(categoryId)
export const getItemsInCategory = async (categoryId) => {
console.log(`firebase category id is ${categoryId}`)
const snapshot = await db.collection('Item').where('category', '==', categoryId).get()
return snapshot.docs.map(doc => {console.log("called");return {id: doc.id, ...doc.data()}});
}
Right now, my application shows the list of items in the given Category. However, the list does not get updated when a new Item is added to the category by someone else. In other words, additions in FireStore collection does not reflect on my screen unless I refresh the page.
How can I code my webapp in such a way that any change on the FireStore end gets reflected on my webapp?
Thanks in advance!
Your code is doing a one-time query with get(). Queries made like this are not realtime. They don't refresh.
If you want to receive updates to your query in realtime, you should follow the documentation for realtime queries. Instead of using get(), you will use onSnapshot(). And instead of getting a promise, you will attach a listener callback that will be invoked whenever there is a change in the results of the query. Because of these differences, your code will look drastically different.

How to retrieve, store, and update data in Firestore using React Hooks

I'm trying to retrieve data (let's say a list of todos) from Firestore and render it to the DOM, but I'm unsure how to properly do this/what the best practice is. Do I retrieve the data from Firestore using useEffect and onSnapshot and store it in state? When adding, deleting, and/or changing data (todos), is it as simple as just using the .add(), .delete(), .update() Firestore methods to update the database, and thus updating the DOM (because of the onSnaphot)?
The code below works, but I'm interested in learning the best way to go about this problem. I heard storing data in state isn't a very good idea so that is another reason I'm asking.
const [ todos, setTodos ] = useState([])
useEffect( () => {
const db = firebase.firestore().collection('todos')
db.onSnapshot( snapshot => {
const retrievedTodos = []
snapshot.forEach( doc => {
retrievedTodos.push({...doc.data(), id: doc.id})
})
setTodos(retrievedTodos)
})
}, [])
return (
<div>
{todos.map( todo => {
return <TodoItem
text={todo.text}
key={todo.id} />
})}
</div>
)

Resources