React Native setState not working when I loop through an array - reactjs

I have a state where I store all the uuids of the posts. I am retrieving the uuids of the posts in useEffect() from firebase and looping through the array of uuids and retrieving all the posts that the user made but the posts state is returning an empty array.
useEffect(() => {
getData();
}, []);
const getData = () => {
setPosts([]);
setPostuuids([]);
firebase
.firestore()
.collection("users")
.doc(uid)
.get()
.then((doc) => {
setPostuuids(doc.data().posts);
});
postuuids.filter((postuuid) => {
firebase
.firestore()
.collection("posts")
.doc(postuuid)
.get()
.then((doc) => {
const image = doc.data().image;
const text = doc.data().text;
const userid = doc.data().uid;
const timestamp = doc.data().timestamp;
const username = doc.data().username;
const uuid = doc.data().uuid;
const name = doc.data().name;
const avatar = doc.data().avatar;
setPosts((prevPosts) => [
...prevPosts,
{
image: image,
timestamp: timestamp,
text: text,
name: name,
userid: userid,
uuid: uuid,
username: username,
avatar: avatar,
},
]);
});
});
};

your postuuids.filter run before request completed, so postuuids is empty.
you should use another useEffect() for postuuids.map():
useEffect(() =>{
postuuids.map((postuuid) => {
firebase
.firestore()
.collection("posts")
.doc(postuuid)
.get()
.then((doc) => {
const image = doc.data().image;
const text = doc.data().text;
const userid = doc.data().uid;
const timestamp = doc.data().timestamp;
const username = doc.data().username;
const uuid = doc.data().uuid;
const name = doc.data().name;
const avatar = doc.data().avatar;
setPosts((prevPosts) => [
...prevPosts,
{
image: image,
timestamp: timestamp,
text: text,
name: name,
userid: userid,
uuid: uuid,
username: username,
avatar: avatar,
},
]);
});
});
};
},[postuuids])

Use map method instead of filter to loop through a list.
Best Regards!

Related

Firebase v9 signup a new user and store users in a users collection

I am able to sign up a new user, but how can I store that user in a collection in firestore? I am not sure with firebase v9 if the addDoc function is in the right place, but I don't know where else or how to code it.
export const useSignup = () => {
const [error, setError] = useState("");
const { dispatch } = useAuthContext();
const signup = (email: string, password: string, username: string) => {
setError("");
createUserWithEmailAndPassword(auth, email, password)
.then((res) => {
dispatch({ type: "LOGIN", payload: res.user });
const uid = res.user.uid;
const data = {
id: uid,
email,
username,
};
const ref = collection(db, "users");
addDoc(ref, {
data,
});
})
.catch((err) => {
setError(err.message);
});
};
return { error, signup };
};
To create a user-document for a newly signed-up user, you can do the following:
Access their bid from the user object (like you already did).
Create a document reference whose path ends in the above mid. Be aware that this document does not exist yet.
Use the setDoc method with above document reference, and user data to be stored as inputs.
It looks like the following in the form of code:
const uid = res.user.uid;
const data = {
id: uid,
email,
username,
};
const ref = collection(db, `users/${uid}`);
setDoc(ref, data)
.then(() => console.log("Created New User Document Successfully"))
.catch(() => console.log("Error"))
You must write the above code right after your dispatch call. Hope this helps!

Problem with uploading multiple images in Firebase v9

I have a problem with uploading multiple images in Firebase v9! It works but only with 1 image, even though I'm mapping through my array.
Everything works as I expect until the last part where it doesn't perform the uploading task for every image...
What am I doing wrong? Thank you in advance!
Here my code:
const addImagePost = () => {
for(let i = 0; i < event.target.files.length; i ++) {
const newImage = event.target.files[i]
setSelectedFiles((prevState => [...prevState, newImage]))
}
}
const uploadPost = async (e) => {
e.preventDefault()
if(loadingPost) return;
setLoadingPost(true)
const docRef = await addDoc(collection(db, 'posts'), {
userID: user?.userUID,
username: user?.userName,
caption: inputPost,
profileUser: user?.userPhoto,
timestamp: serverTimestamp()
})
const imageRef = ref(storage, `files/${docRef.id}/image`)
// It only displays the last image of the array
selectedFiles?.map(async(file) => (
await uploadBytes(imageRef, file, 'data_url').then(async () => {
const downloadURL = await getDownloadURL(imageRef)
await updateDoc(doc(db, 'posts', docRef.id), {
image: downloadURL
}, {merge: true})
})
))

Firestore add another map to an array field in React

I am working on a front end project with React and Firebase.
I would like to create a database where registered users can save their recipes by clicking on the RecipeCard button.
However with a click on another card, the contents of the field are overwritten and not added to the main recipeDb array.
Is there a solution?
here the img of my db
And here the code:
const dbFavorites = (e) => {
const recipeDb = [
{
Recipe: title,
Id: id,
Source: source,
},
];
fire.auth().onAuthStateChanged((user) => {
if (user) {
const dbAdd = fire
.firestore()
.collection("User-favorites" + user.uid)
.doc(user.uid)
.update({ recipeDb });
}
});
};
The function dbFavorites is used in the button:
<button
type="button"
onClick={() => {
dbFavorites();
}}
>
I state that FieldValue.arrayUnion gives me an error and I don'have a backend...
Update: I tried to use arrayUnion in this way (instead of the previous function):
const dbFavorites = (e) => {
const recipeDb = [
{
Recipe: title,
Id: id,
Source: source,
},
];
fire.auth().onAuthStateChanged((user) => {
if (user) {
const dbAdd = fire
.firestore()
.collection("User-favorites" + user.uid)
.doc(user.uid)
.update({ fav: fire.firestore.FieldValue.arrayUnion(recipeDb) });
}
});
};

push object to array react native

I need to get specific users who have the serviceClientID field in the firestore.
those that do, I insert it into the array and put it in my state chats (setChat).
but the problem is that only one user is entering my state and I have two users with this field.
why is only 1 entering and not 2?
code below:
firebase.auth().onAuthStateChanged(async ({ uid }) => {
const servicesCollection = await firestore()
.collection('Providers')
.doc(uid)
.collection('ServiceHistory')
.get();
servicesCollection.docs.forEach(async item => {
if (item.exists && item.data().serviceClientID) {
const clientsCollection = await firestore()
.collection('Clients')
.doc(item.data().serviceClientID)
.get();
// if (item.data().serviceClientID === clientsCollection.id) {
const values = {
id: clientsCollection.id,
name: clientsCollection.data().name.last,
uid,
};
const arr = [];
arr.push(values);
// }
console.log('arrayay', arr);
setChats(arr);
}
});
});
Cause every loop you empty an array.
You have to get the {arr} out of the function. then you need to push the data inside.
const firebaseFunc = () => {
let arr = [];
firebase.auth().onAuthStateChanged(async ({ uid }) => {
const servicesCollection = await firestore()
.collection('Providers')
.doc(uid)
.collection('ServiceHistory')
.get();
servicesCollection.docs.forEach(async item => {
if (item.exists && item.data().serviceClientID) {
const clientsCollection = await firestore()
.collection('Clients')
.doc(item.data().serviceClientID)
.get();
arr.push({
id: clientsCollection.id,
name: clientsCollection.data().name.last,
uid,
});
});
});
setChats(arr);
console.log('arrayay', arr);
}

How to fetch one document from Firebase and how to pass the id to delete it?

this is my react native + firebase project and i have got 2 questions:
How do you suggest to pass the id from one CV ?
How do i fetch only one CV from firebase, cause if i try this it gives me this error:
TypeError: undefined is not an object (evaluating 'querySnapshot.docs.map')]
fetching all the documents from the collection is fine
getCv: () => {
const id = "eccc137b-88be-470d-a0b8-c90b58a6473a"
return firebase
.firestore()
.collection('cvs')
.doc(id)
.get()
.then(function(querySnapshot) {
let cvs = querySnapshot.docs.map(doc => doc.data())
// console.log(doc.data())
return cvs
})
.catch(function(error) {
console.log('Error getting documents: ', error)
})
}
This is my fetchCV method
fetchCvs = async () => {
try {
const cvs = await this.props.firebase.getCv()
//const cvs = await this.props.firebase.getCvs()
//console.log(cvs)
this.setState({ DATA: cvs, isRefreshing: false })
} catch (e) {
console.error(e)
}
}
This is how i add one CV
onSubmit = async () => {
try {
const cv = {
photo: this.state.image,
title: this.state.title,
description: this.state.description,
salary: this.state.salary,
createdAt: new Date().toISOString()
}
this.props.firebase.uploadCv(cv)
this.setState({
image: null,
title: '',
description: '',
salary: '',
createdAt: ''
})
} catch (e) {
console.error(e)
}
}
uploadCv: cv => {
const id = uuid.v4()
const uploadData = {
id: id,
cvPhoto: cv.photo,
cvTitle: cv.title,
cvDescription: cv.description,
cvSalary: cv.salary,
cvCreatedAt: cv.createdAt
}
return firebase
.firestore()
.collection('cvs')
.doc(id)
.set(uploadData)
},
and This is how i implemented the deleteCv method
onDelete = async () => {
const cvId = {
id: this.state.title
}
//this.props.firebase.deleteItem(cv);
const deleteId = this.props.firebase.deleteItem(cv);
console.log(deleteId)
}
I have different error, when I try similar code in nodejs, but I think its the same reason. In line:
let cvs = querySnapshot.docs.map(doc => doc.data())
As you are using get on DocumentReference querySnapshot is instance of DocumentSnapshot which does not have property docs. I think you should use querySnapshot.data() first and than manipulate on data returned.
Or maybe you wanted to use get on collection, not on document, and than you will get QuerySnapshot object and .doc array will be available.

Resources