Ok my question is pretty basic, in my app I have a post system, and in that post you can like the post. So when the user clicks the like button, I want the database to update the likes. Only problem is... I don't know how to capture the collections data
This is what the data looks like, its a randomly generated collections id, I tried to set the collections id to the id of the user but that would mean I can't make multiple posts. Can anyone help on this?
You can store previous value of likes inside a variable using the get function present in Firestore. Then you can update a field in the Firestore document inside a collection using updateDoc method using the value as shown below
import {
getFirestore,doc,getDoc,updateDoc
} from 'firebase/firestore';
async function updateData() {
const docRef=doc(db,’collection’,’document’);
const docData=await getDoc(docRef);
var value=docData.get('likes');
updateDoc(docRef,{likes:value+1});
}
updateData();
Or you can use the increment function present in Firestore. It will increment your field directly and you won’t have to create a variable separately to store the previous value as shown in Add data
import {
getFirestore,doc,getDoc,updateDoc, increment
} from 'firebase/firestore';
async function updateData() {
const docRef=doc(db,’collection’,’document’);
await updateDoc(docRef,{likes:increment(1)});
}
updateData();
You can learn more about the update() in Update a document.
Related
I have a page of objects. These objects are retrieved from a json file in a firebase realtime database. On the page, I have put a checkbox input with each object.
Here's what I need: when the user checks off an object, the real time database is updated with a key value such as changed: true.
I've tried using the update function imported from firebase but doesn't seem to work.
Here is my handle function that controls the way my objects look when the corresponding checkbox is selected...
const handleCheckboxChange = (object) => {
if (selectedObjects.includes(object)) {
setSelectedObject(selectedObject.filter(b => b !== object));
} else {
setSelectedObject([...selectedObject, object]);
}
`
This works in changing the page, but how exaclty do I go about adding code to update to realtime database that the objects are selected?
I'm developing an app using React Native that allows you to create your own checklists and add items to them.
For example you'd have "Create Checklist", and inside that you'll have the option to "Add Item", "Delete Item" "Edit Item", basic CRUD methods etc.
It's going to be completely offline but I'm wondering what the best approach to storing this data locally would be.
Should I be using a DB such as firebase? I have read that it is overkill and to use something like Redux but I'm not sure if the latter will accomplish everything I need. As long as it's storing data which can be edited, and will save on the user's device (with minimal effort) it sounds good to me.
Would appreciate some input on this, thanks!
You could use AsyncStorage for persisting data locally on the user's phone. It is a simple persistent key-value-storage.
Each checklist is most likely an array of JS objects. The documentation provides an example on how to store objects.
const storeData = async (value) => {
try {
const jsonValue = JSON.stringify(value)
await AsyncStorage.setItem('#storage_Key', jsonValue)
} catch (e) {
// saving error
}
}
The value parameter is any JS object. We use JSON.stringify to create a JSON string. We use AsyncStorage.setItem in order to persist the data. The string #storage_Key is the key for the object. This could be any string.
We retrieve a persisted object as follows.
const getData = async () => {
try {
const jsonValue = await AsyncStorage.getItem('#storage_Key')
return jsonValue != null ? JSON.parse(jsonValue) : null;
} catch(e) {
// error reading value
}
}
Both examples are taken from the official documentation.
Keep in mind that this functionality should be used for persistence only. If the application is running, you should load the complete list, or parts of the list if it is very large, in some sort of application cache. The implementation for this functionality now heavily depends on how your current code looks like. If you have a plain view, then you could access the local storage in an effect and just store it in a local state.
function MySuperList() {
const [list, setList] = useState([]);
React.useEffect(() => {
// retrieve data using the above functionality and set the state
}, [])
// render list
return (...)
}
I would implement some sort of save button for this list. If it is pressed, then we persist the data in the local storage of the phone.
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.
Actually am new in react and am trying to create an event app in which a user can join an event
here is code for joining an event
export const JoinEvent = (id) => {
return async dispatch => {
let data = await firebase.firestore().collection('Events').doc(id).get()
let tmpArray = data.data()
let currentUser = firebase.auth().currentUser
let newArray = tmpArray.PeopleAttending
await firebase.firestore().collection('Events').doc(id).update({
PeopleAttending : {...newArray, [currentUser.uid]: {displayName : currentUser.displayName}}
})
}
}
actually i have created an action bascailly in JoinEvent an id is passed of the particular event which is clicked.
here is my firestore structure look like this..
so basically i have to download the whole data and store in local array and then add new user and then finally update
So here am basically download the whole data is there any way to just simply add new Object without downloading whole data??
thankyou
You are doing it wrong. Firestore document size limit is Maximum size for a document 1 MiB (1,048,576 bytes), so sooner or later you're going to reach that limit if you keep adding data like this. It may seems that you're not going to reach that limit, but it's very unsafe to store data that way. You can check Firestore query using an object element as parameter how to query objects in firestore documents, but I suggest you don't do it that way.
The proper way to do it, is to create a subcollection PeopleAttending on each document inside the Events collection and then use that collection to store the data.
Also you can try document set with merge or mergeFields like documented here https://googleapis.dev/nodejs/firestore/latest/DocumentReference.html#set and here https://stackoverflow.com/a/46600599/1889685.
export default class App extends Component {
state = {
data: []
};
fetchData = async () => {
const response = await fetch("https://randomuser.me/api?results=5"); // Replace this with the API call to the JSON results of what you need for your app.
const json = await response.json();
this.setState({ data: json.results }); // for the randomuser json result, the format says the data is inside results section of the json.
};
So, I have this code in my App.js file for React Native. The randomuser.me is a website that just gives you random users. Using it as a test URL right now. I don't really understand what the code is doing enough to be able to use it for other parts of my project. I was able to successfully display the 5 user results but now I want to access them again and iterate through the data attribute of the state.
tldr; Can I just access the data I got from the fetch in a for loop using data[i]? Please advise. I want to see if user input matches any of the items in the response that is stored in data attribute of state.
Ok the thign that you just did, that is fetch. You retrieve data from the internet.
"https://randomuser.me/api?results=5" is an API, there is lot of different API's, and each one has it´s own way to retrieve data from. if you put "https://randomuser.me/api?results=5" in your browser, you are gonna see a JSON, some API's store data in JSON, others in an array format.
In this case, the JSON, has just one child, 'results', thats why you store "json.results".
That´s fetch. The thing that you want to do is just javascript.
Store json.results in a variable
then iterate over it
var Results = json.results //store it in a variable
for(var i = 0;i<Object.keys(Results).length;i++){ //iterate
var CurrentUser = Results[Object.keys(Results)[i]] // i use this because some JSOn have random keys
if(CurrentUser.gender==='male'){//if you meet a condition
//do whatever you want
}
}
you can also use ".map" if it´s an array