Adding a collection to a document in Firestore - reactjs

The way I have my file structure set up right now is that I have a main folder calles users. In that folder we have a document with a randomly generated name that contain some information along with another folder for files. I would like to duplicate this only using code. I could either run a function to build a template from scratch, or build a function to duplicate a file along with its subfolders.
Fyi, the file tree goes as such - [users] -> [user_document/user_information] -> [images]
I have yet to find any resources about this online, or maybe I'm not looking in the right areas, either ways, thanks for your help.

To add a new document to a collection, use the add method on a CollectionReference:
import firestore from '#react-native-firebase/firestore';
firestore()
.collection('Users')
.add({
image: "https://images.pexels.com/photos/10640445/pexels-photo-10640445.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
})
.then(() => {
console.log('User added!');
});
The add method adds the new document to your collection with a random unique ID. If you'd like to specify your own ID, call the set method on a DocumentReference instead:
import firestore from '#react-native-firebase/firestore';
firestore()
.collection('Users')
.doc('ABC')
.set({
image: "https://images.pexels.com/photos/10640445/pexels-photo-10640445.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
})
.then(() => {
console.log('User added!');
});
For more details refer to the docs
Hope this helps. Happy Coding :)

Related

I can't order my firestore data by multiple fields. React

I have a collection called list which I'm trying to order by 3 different fields: important, unimportant and date, so the unimportant come first (they'll be at the bottom of the list, important the last, and all that sorted by timestamp.
If i query to order my docs by any of the above on its own, then it works, trouble starts when I try to put them together as per firestore documentation. So I have the following code:
const q = query(listRef, orderBy("important", "desc"), orderBy("unimportant"), orderBy("date"));
Which gets me Uncaught Error in snapshot listener. This is how i get my data from firestore:
const getData = () => { // get data from firestore to app
onSnapshot(q, (snapshot) => {
firestoreList = [];
firestoreIds = [];
snapshot.docs.forEach((doc) => {
firestoreList.push({ ...doc.data(), id: doc.id });
!firestoreIds.includes(doc.id) && firestoreIds.push(doc.id);
});
if (firestoreList.length === 0) {
setItems(items.concat(newItem));
} else {
setItemIds(firestoreIds);
setItems(firestoreList);
}
});
}
useEffect(() => {
getData();
}, []);
I'm using onSnapshot, because i need the user to be able to add, remove and do other stuff with data and see the outcome reflected immediately for them and for other users who'll be using the app simultaneously.
Ordering/filtering on multiple fields requires that your database contains a so-called composite index on those fields. And unlike single-field indexes, which are created automatically, composite indexes are only created when you explicitly tell the database to do so.
If you log the warning/error message you get, it contains a long direct link to the Firestore console to create the exact index the query needs. The link has all details already filled in, so all you have to do is click the link and then click the button to start creating the index.
Also see:
Firestore order by two fields
How to query one field then order by another one in Firebase cloud Firestore?
the Firestore documentation on ordering a Firestore query on multiple fields.

React js backend how to get the price_data info from stripe.checkout.session.line_items and push the data into firestore

I am trying to push the stripe checkout line_items price data to firestore by creating a webhook functions using react node js as the below code shown.
exports.stripeWebhook=functions.https.onRequest(async (req, res)=>{
const stripe = require("stripe")(functions.config().stripe.token);
let event;
try {
const whSec=functions.config().stripe.payments_webhook_secret;
event =stripe.webhooks.constructEvent(
req.rawBody,
req.headers["stripe-signature"],
whSec,
);
} catch (err) {
console.error("Webhook signature verification failed.");
return res.sendStatus(400);
}
const dataObject=event.data.object;
const session = await stripe.checkout.sessions.retrieve(dataObject.id, {
expand: ['line_items']
});
await admin.firestore().collection("customer").doc(String(dataObject.customer_email)).collection("order").doc().set({
checkoutSessionId:dataObject.id,
paymentStatus: dataObject.payment_status,
shppingInfo:dataObject.shipping,
amountTotal:dataObject.amount_total/100,
customerId:dataObject.customer,
CustomerEmail:dataObject.customer_email,
orderItems:session.line_items.price_data,
});
return res.sendStatus(200);
});
The function works fine except orderItems:session.line_items.price_data, it shows an error as an undefined firestore value. if I change to orderItems:session.line_items, it has no error, but the line_items info shown in firestore (screen shot below is not what I want, I just want the line_items.price_data which include just item title, price and images.
My question is how to get each item price_data from line_items?
You could try using the listLineItems method instead, and expand the product object inside data.price.product (according to the guide for expanding nested objects in lists).
const lineItems = await stripe.checkout.sessions.listLineItems(id, {expand: ['data.price.product']})
As you are currently retrieving the Session object with the expanded line_items data, this data won't include the product's name, images, description, etc. It looks like the problem is caused by these API calls, as opposed to something in your Firebase function or Firestore.
We can see that the product data from list_items.data.price.product is shown as expandable, which confirms it needs to be expanded. It also seems that there is no price_data field (but instead only price) nor product_data (but instead product) within the responses. These specific fields are apparently available only when creating Sessions.
You would end up with something like:
await admin.firestore().collection("customer").doc(String(dataObject.customer_email)).collection("order").doc().set({
//...
orderItems: lineItems.data[0].price //includes product details from nested expand
});
Since line items data is an array containing each item, you would need to build the array to save in Firestore as your use case requires. Let me know if this was helpful.

Trying to read products from back4app onto a web page with carditem view React & Back4APP

I am currently trying to produce a forum page where users can post products onto a forum page for other users to see. I have it writing to the db and saving the products - however i now want to read back from the products and produce each product for other users to see. Cant seem to find much guidance on it.
enter image description here
Image is current code of the readProducts function that I have created. Thanks
(async () => {
// Creates a new Query object to help us fetch MyCustomClass objects
const query = new Parse.Query('MyCustomClass');
try {
// Executes the query, which returns an array of MyCustomClass
const results = await query.find();
console.log(`ParseObjects found: ${JSON.stringify(results)}`);
} catch (error) {
console.log(`Error: ${JSON.stringify(error)}`);
}
})();

How to show the data category wise in MERN?

I am currently developing a small web app using MERN. Here I have developed the backend part and frontend part of it. I want to get the response data category-wise. For example, in my database there are details of assets(Laptops, mobiles etc) with attributes like assetName and assetCategory. There's a functionality to search those assets category-wise. In the frontend, I have used a search bar and user can type the category of asset which is wanted to see. Then backend server gives the response of that. I have developed routes and controllers for the backend part and I will show the controller here.
//find assets by category
exports.assetsByCategory = async(req,res) => {
const CATEGORY = req.body.assetCategory;
const asset = await Asset.find({"assetCategory" :{$regex: new RegExp([CATEGORY?.toLowerCase()], "i") }})
.then((assets)=>{
res.json(assets)
}).catch((err)=>{
console.log(err);
res.status(500).send({message:"No assets like that category!",error:err.message})
})
}
The code for this function which is in the frontend part will be shown here.
function searchCategoryBar(e)
{
e.preventDefault();
const searchedCategory = {assetCategory}
console.log(searchedCategory)
axios.get("http://localhost:8070/assets/category",searchedCategory).then((asset)=>{
setAssets(asset.data);
console.log(asset.data);
}).catch((err)=>{
alert(err.message);
})
}
So that, when I type "lap" on the search bar and then the response must be shown the asset list of laptop category. But in here, response shows all the assets lists without category-wise.
Please give me some help to solve this issue, Thank you!

Is there a way to delete a collection in firebase with react?

I was looking at the docs, but they just have this stated:
// Deleting collections from a Web client is not recommended.
For reference, I'm moving a document from 1 collection to another and that document has subcollections.
To move it I do the following:
set the new document (path is a path to the new collection to place the doc in)
copy the collections from the old document to the new document
setDoc(doc(db, path), inquiry);
console.log(updatesCollection);
updatesCollection.docs.map((updateDocument) => {
(async () => (addDoc(collection(db, `/closed/${id}/updates`), updateDocument.data())))();
});
delete the old document
(async () => await deleteDoc(doc(db, "active/" + id)))();
this leaves the old path open and the subcollection still there, is there a way I can delete it? this is a full react app so I want to do it client-side.
this leaves the old path open and the subcollection still there
That's indeed the expected behavior since deleting a document doesn't mean that all subcollections that exist within that document will be deleted as well.
As the error message states:
Deleting collections from a Web client is not recommended.
Don't do that. If you want to delete a document along with all the documents within its subcollections, please note that you have to do it manually.

Resources