How can I make an update in array of objects in firebase? - reactjs

I am having a questions collection inside which I am having an array answersContent.answersContent array will consist ans objects.Now here I want to make change in this ans objects.
I want to push user.uid in upvotes when user clicks a button.I have that answerObject as well as whole questions Collection in my component.Can anyone please tell any way to achieve this?
This is the image containing firebase structure
I tried it using this code but this is giving wrong results:
const handleDownvote = ()=>{
if(!downvote){
updateDoc(doc(db, "questions", questionData?.quesId),{
downvotes : arrayUnion(user?.uid)
})
}
else{
updateDoc(doc(db, "questions", questionData?.quesId),{
downvotes: arrayRemove(user?.uid)
})
}
}

Related

Sanity.io Fetching Through References

I'm trying to figure out how to access a full object reference through Sanity.io. Example code:
const fetchExperience = async () => {
const data = await sanityClient.fetch(`*[_type == 'experience'] {
company,
title,
'techStack': stack[]->technology,
'imageUrl': image.asset->url,
}`);
return data;
};
I have another schema declared called Skill that contains two fields: technology, and icon. This Experience schema that I am working with above and references the Skill schema. Using this post, I was able to figure out how to grab a singular field through the reference and populate a field called techStack. However, I want to take this one step further: how can I write a GROQ that returns me an array of objects that might look like this?:
[
{ technology: 'React.js', icon: 'pretend-this-is-a-link-to-an-asset' },
...
]
Thanks in advance!
You can do this to get the specific fields:
"techStack": stack[]-> { technology, icon }

How to sort how you want the the data from firestore

I have a firestore with lessons, see the picture below, I get from the firestore the title property from each object and display it in the browser, but everytime I refresh the website the lessons are sorted by how they want, why is that happening? I want to sort them how I want, I want to start with 'Introduction' and so on, how can I do that? I think the orderBy() is not working here.
As you see in the image above, the order in the firestore is alphabetical, but in my page is sorted by its own, see the picture below.
I want the result to be by in a specific order, for example we have the following titles, these titles are from the firestore: "Display", "Introduction", "Alignment", my problem is that these 3 titles are in a new order every time I refresh the website, I want them to be: "Introduction", "Alignment", "Display". In my case I have more titles but this is what's happening, I don't know how to align them how I want or even alphabetical if is possible.
Below is the code that I used to get the data from firestore:
useEffect(() => {
db.collection("users")
.doc(`${user.uid}`)
.get()
.then((doc) => {
const allData = { ...doc.data(), id: doc.id };
const intoArray = Object.entries(allData);
intoArray.sort(); // I used sort here because I had the same problem
// (every time a new order) with the
// data when I converted it to an array
const getCSSLessons = intoArray[0][1];
const cssData = Object.values(getCSSLessons);
setCss(cssData);
const getHTMLLessons = intoArray[1][1];
const htmlData = Object.values(getHTMLLessons);
setHtml(htmlData);
const getResLessons = intoArray[3][1];
const resData = Object.values(getResLessons);
setRes(resData);
})
.catch((error) => console.log(error));
}, [user]);
I tried using sort(), for a variable (htmlData) but its not working.
Also, I use map() to display them, if this helps you to answer to my question.
If you use sort without any argument, it will sort array elements alphabetically. It looks like your array elements are arrays, which will end with unexpected behaviors. Use sort argument to ensure it uses your own sorting rules. For example:
const intoArray = Object
.entries(allData)
// I don't know what should be the sorting algorithm
// As an example, I consider each element (`a` and `b`) to
// be arrays and compare both first element as a Number
.sort( (a, b) => a[0] - b[0])
Edit
A more secure way to find elements in an array is to use find:
const getCSSLessons = intoArray[0]
.find( element => element.name === 'CSS Lessons');
I was doing something unnecessary as you see in the first picture I had a main object css and in that object I had sub-objects like alignment and in the sub object I had the properties that I want to display, that sub object was unncessary, istead of sub objects with a pre defined name, I let the firebase to count the sub objects and add as a name a number and the order is the same as I wanted to be.
The code that I used to add data to firebase:
fire
.auth()
.createUserWithEmailAndPassword(email, password)
.then((cred) => {
return db
.collection("users")
.doc(cred.user.uid)
.set({
css: [
{
title: "Introduction",
path: "/css3/introduction",
},
{
title: "Priority",
path: "/css3/priority",
},
],
});

Is it possible to filter Firestore data on multiple, user selected values in Angular

I'm essentially trying to build a product filter where the user can select (or not select e.g. they aren't required) from any of the filter options.
My firestore is setup as:
product
{
colour: "white"
brand: "a brand"
}
Currently I can filter on say 'colour' with this code:
filterProducts(value: string){
this.filteredProducts = this.db.collection('products', ref => ref.where('colour', '==', value)).valueChanges();
}
How can I adapt the above to be able to filter on either colour, brand or both? Is this even possible?
If you're asking whether you can query on multiple fields, the answer is "yes". For example to filter on brand and color:
ref.where('colour', '==', 'white').where('brand', '==', 'a brand')
For more on this see the Firebase documentation on filtering data and compound queries.
You'll of course need to pass both values into your filterProducts method in order to be able to use them.
If you only want to add a condition when the user has given a value for that filter, you'd do something like this:
ref = firebase.firestore.collection(...); // whatever you already have
if (colourValue) {
ref = ref.where('colour', '==', colourValue);
}
if (brandValue) {
ref = ref.where('brand', '==', brandValue);
}

re-base concat is not a function

(I am using re-base, cant create re-base tag)
I am trying to get user input and then append it onto my state arrays: titles, descriptions and content of a blog and store it in firebase realtime database.
I checked other questions and made sure that my states are arrays so that concat would work.
handleEntry(titleInput, descriptionInput, contentInput) {
this.setState({
titles: this.state.titles.concat(titleInput),
descriptions: this.state.descriptions.concat(descriptionInput),
contents: this.state.contents.concat(contentInput)
})
}
I thought that my state would be updated by instead has a TypeError:this.state.titles.concat is not a function
However, the error points it here at the full stop before syncState:
this.contentsRef = base.syncState('contents', {
context: this,
state: 'contents'
})
UPDATE: I'm not sure if this is the way to do it, but it works. Instead of assigning the state using the state's value, I used a placeholder then assigned it to the state.
handleEntry(titleInput, descriptionInput, contentInput) {
var titleHolder = [...this.state.titles].concat(titleInput);
var descriptionHolder = [...this.state.descriptions].concat(descriptionInput);
var contentHolder = [...this.state.contents].concat(contentInput);
this.setState({
titles: titleHolder,
descriptions: descriptionHolder,
contents: contentHolder
})
}

Filter React Native Data

I searched all day but I didn't find the solution to my problem.
I'm new to React Native so I'm stucked ...
Here's my problem :
I fetch an api to the get data, I'm doing it with axios and it's ok I can render my component !
Then I don't want to display ALL ITEMS of my Array but I want to display some items according to different values with 2 buttons :
<Button onPress={Get ALL ITEMS with this value}/>
<Button onPress={Get ALL ITEMS with ANOTHER VALUE} />
My issue is that I'm modifying the state of my array 'products' with new information but that's not what I want. I always want that I'm displaying information according to a particular VALUE in the Array and still get my Full Array...
Here's some piece of code of what I'm doing :
onPressFirstButton() {
let newArray = [...this.state.products];
this.setState({
products: newArray.filter(function(product){
return product.value == 32;
})
});
}
onPressSecondButton() {
let otherArray = [...this.state.products];
this.setState({
products: otherArray.filter(function(product){
return product.other_value == 389;
})
});
}
I'm sure it's not the best way because it's not working.. I hope you will understand what I'm trying to say..
Thank you
Since you seem to be using the products property to populate your template, consider using a separate variable for that instead, that way you don’t have to mess with your state when doing your filtering. Maybe this will help:
displayProducts = []
onPressFirstButton () {
this.displayProducts = this.state.products.filter(product => /* logic */)
}

Resources