Map few docs with NextJs and Firebase - firebase

hope you have an amazing day!
i'm new with NextJs and i have a problem when i have to map my Firebase documents, i need to put 5 cards in my web, but i setting all the documents that i have.
this is my call ref
const [posts, setPosts] = useState([]);
useEffect(() => {
(async () => {
const callref = collection(db, "posts", limit(3));
const snapshots = await getDocs(callref);
if (posts.length < 5) {
const docs = snapshots.docs.map(doc => {
const data = doc.data()
data.id = doc.id
return data
});
setPosts(docs);
console.log(docs)
} else {
return;
}
})()
}, [])
and this is the map code in my web
{
posts.map((post) => (
<div className="contProduct">
<div className="imageProduct">
<img src={post.image}></img>
</div>
<div className="descriptionProduct">
<h3>{post.title}</h3>
<p>{post.subtitle}</p>
</div>
</div>
))
}
i tried putting an if sentense but it shows me an error, i dont know how to show only five posts.
Thank you for your time and I hope you can help me.

I'm not sure if I understand the question well, but maybe what you need is using the firestore limit() function, just like this :
const callref = collection(db, "posts", limit(3));
callRef.limit(5);
const snapshots = await getDocs(callref);

Related

Firestore pagination and Vue

I am trying to create Infinite scrolling pagination with Vuejs and Firestore.
So far I have been able to get the code to work in the sense that it is fetching and showing the data as intended. However when the new query is constructed after scrolling down to the bottom, the original query with the same values loads again.
It seems that I am doing something wrong with the startAfter() method, which is supposed to get the next values in the firestore query.
This is my setup:
setup() {
const latestDoc = ref(null);
const getFoods = ref([]);
onMounted(() => {
runQuery(latestDoc.value);
});
const runQuery = async (doc) => {
let q = query(collection(db, "foods"), orderBy("title"), startAfter(doc), limit(5));
const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
getFoods.value.push({ ...doc.data(), id: doc.id });
});
};
const loadData = (InfiniteScrollCustomEvent) => {
InfiniteScrollCustomEvent.target.complete();
latestDoc.value = getFoods.value.length - 1;
runQuery(latestDoc.value);
};
return { getFoods, optionsOutline, loadData, latestDoc, runQuery };
},
Can anyone tell me what I am doing wrong?

How do I deconstruct and display res from strapi api with usestate?

Im trying to display the titles, price, description and allergies from the strapi Api:http://localhost:1337/api/pizzasarpsborgs.
api
Not really sure how to deconstruct the res. Can someone help?
This is my current code:
export default function Menu() {
const [pizzasarpsborgs, setPizzas] = useState(['']);
async function fetchPizza() {
const res = await fetch('http://localhost:1337/api/pizzasarpsborgs');
const data = await res.json();
setPizzas(data.data);
}
useEffect(() => {
fetchPizza();
}, []);
return (
<div>
{pizzasarpsborgs.map((pizza) => (
<p key={pizza.id}>{pizza.id}</p>
))}
</div>
);
}```
can you try the following and let me know if it works.
{pizzasarpsborgs.length ? pizzasarpsborgs.map((pizza) => (
<div key={pizza.id}>
<h1>{pizza.attributes.title}</h1>
<p>{pizza.attributes.price}</p>
<p>{pizza.attributes.description}</p>
<p>{pizza.attributes.allergies}</p>
</div>
)) : null}
I don't have the development environment setup as of now, so I am writing this off the top of my head. So please let me know if any errors pop up.

react native data show on console.log but not on screen

Sometimes the app working well.
but I dont know why, sometimes the data from firebase give me blank screen instead of the data.
after I reopen the app it work.
for example,
one of my pages:
useEffect( () => {
const subscriber = firestore()
.collection('Trails')
.onSnapshot(querySnapshot => { //const querySnapshot = await firebase.firestore().collection('users').get();
const trails = [];
console.log('subscribe')
if (querySnapshot)
querySnapshot.forEach(async documentSnapshot => {
trails.push({
...documentSnapshot.data(),
key: documentSnapshot.id,
});
console.log("trails test", trails)
});
setTrails(trails);
setLoading(false);
});
return () => {subscriber()};
}, []);
I made useEffect to get the data from DB then show it, and same - sometimes give me blank and sometimes works well.
I want to publish the app but im not satisfying with this bug?
sorry for my English, I dont even know how to describe this problem better.
Please can anyone guide me through? maybe my useEffect not doing well?
I think you should use debugging.
React native documentation
Stackoverflow question
I think there's issue with the return in useEffect return is called when componeent unmounts. here's an example how i handle async data fetching:
...
const [data, setData] = useState([]);
const isCurrentView = useRef(true);
useEffect(() => {
if (isCurrentView.current === true) {
const asyncFetch = async () => {
const response = await fetch(...something) //here some Asynchronous Call Like(axios, fetch)
setData([...response]);
};
asyncFetch();
}
return () => {
isCurrentView.current = false;
};
}, []);
...
im not 100% sure if this is the VERY best approach, but i have seen similar code in places so i addopted this.
problem was solved:
the setTrails was under scope and it kept refreshing with empty data.
querySnapshot.forEach(async documentSnapshot => {
trails.push({
...documentSnapshot.data(),
key: documentSnapshot.id,
});
setTrails(trails); // <<<~~~~ put the set in this scope.
});
setLoading(false);
});

Accessing the first <ul> element under the div

I am new to web scraping and I was trying to create a simple web scraper using a tutorial. I did that, however, I wanted to try implementing another feature on my own. In the link (https://old.reddit.com/r/programming/), I was trying to fetch all the bullet points from the 'guidelines' (On the right side of the page). Right now, I am able to scrape and get all the information from the 'guidelines', 'info', and 'relatedReddits'. However, I was only trying to get the information from the 'guidelines'. Does anyone know how I can modify my code to access only the first ul tag under the div because right now, it accesses all. Thanks for stopping by.
const axios = require('axios');
const cheerio = require('cheerio');
const getPostTitles = async () => {
try{
const {data} = await axios.get('https://old.reddit.com/r/programming/');
//console.log(data);
const $ = cheerio.load(data);
const guidelines = [];
const postTitles = [];
// to get text in form of array
$('p.title > a').each((idx, el) => {
const postTitle = $(el).text();
postTitles.push(postTitle);
});
$('.md ul li').each((idx, el) => {
const guideline = $(el).text();
guidelines.push(guideline);
});
console.log(guidelines);
return postTitles;
}
catch(error){
throw error;
}
}
getPostTitles()
.then((postTitles) => console.log(postTitles))
.catch(err => console.log(err));
$('.md').find('ul').first().each((i, el) => {
const guideline = $(el).text();
guidelines.push(guideline);
});
This was the solution for anyone that comes here to look.

Nuxtjs getting firestore data within asyncData

I'm trying to convert my VueJS app to NuxtJS to work with SSR. I'm stuck trying to get data loaded with asyncData. When I add my query to a 'mounted() {}' function it works fine but I can't get it to work with asyncData(){} so that I can use SSR.
Does anyone have any idea how to fix this.
My code:
<ul>
<li v-for='province in provinces' v-bind:key="province.id"> {{province.name_nl}}</li>
</ul>
asyncData () {
return { msg: 'Welcome to my new app' }
const moment = require("moment");
var date = moment(new Date()).format("YYYY-MM-DD");
let housesArray = []
let provincesArray = []
return firebase.firestore()
.collection('provinces')
.get()
.then(querySnapshot => {
querySnapshot.forEach(doc => {
provincesArray.push(doc.data());
});
return {provinces: provincesArray}
});
},
Or is there another way I should be doing this? Keeping in mind that it does have to work with SSR.
PS: Yes this code is inside my pages folder, not the component, I know that's not allowed.
When using asyncDate() you can add the async and await keywords to wait for the response(s) before returning them.
How I solved it:
async asyncData () {
const moment = require("moment");
var date = moment(new Date()).format("YYYY-MM-DD");
let housesArray = []
let provincesArray = []
await firebase.firestore()
.collection('provinces')
.orderBy('name_nl')
.get()
.then(querySnapshot => {
querySnapshot.forEach(doc => {
provincesArray.push(doc.data());
});
});
await firebase.firestore()
.collection("houses")
.where("valid_until", ">", date)
.get()
.then(querySnapshot => {
querySnapshot.forEach(doc => {
housesArray.push(doc.data());
});
});
return {
provinces: provincesArray,
houses: housesArray
}
},

Resources