I have done a lot of research and read through multiple stackoverflow questionso on firebase. Some were kind of helpful. But none that particularly helped my problem. I am trying to make a menu planner. There for I need more than one check to test if for example. Date exists, serviceType is === to “lunch” || “dinner”.
I have a function that adds and image saves url and input data to a state in react. I then use, useEffect to listen for the state update and send the data to firebase. I only want to send new data to firebase IF all the checks pass and they don’t exists. Other wise I want to update my data. I have tried. Foreach, for in, ref(‘link/’+ localState.id). Many different methods that I can’t seem to get right.
This is the form Submit function:
const handleSubmit = (e) => { e.preventDefault(); if (image) { const uploadTask = storage.ref(`images/${image.name}`).put(image); uploadTask.on( "state_changed", (snapshot) => { const progress = Math.round( (snapshot.bytesTransferred / snapshot.totalBytes) * 100 ); setProgress(progress); }, (error) => { setError(error); }, () => { storage .ref("images") .child(image.name) .getDownloadURL() .then((url) => { const value = state.serviceType; const keys = Object.keys(value); var filtered = keys.filter(function (key) { return value[key]; }); /////////I have also tried this method, to use one function for all instead of using useEffect////// const mealData = db().ref().child("meals"); const newMealdata = mealData.push(); // newMealdata.set({ // serviceId: newMealdata.key, // date: props.dates, // serviceType: filtered, // service: { // mealService: state, // image: url, // }, // }); /////////////////////////////////////////////// setNewState((prev) => { return { ...newState, date: props.dates, serviceType: filtered, serviceId: newMealdata.key, service: state, }; }); setProgress(0); }); } ); } else { setError("Error Please Choose an Image to Upload"); } };
useEffect function
useEffect(() => { console.log("newState mounterd: ", newState); db() .ref("meals/" + newState.serviceId) .set({ newState }); }, [newState]);
I have tried using the state.id to check if it equals to the snapshot.key and although they do check. firebase still creates a new node of data with the same date, but with different Ids and the data I want to update instead.
So how would it be best to say:
if(snapshot.val().date === props.dates && snapshot.val().serviceId === snapshot.key && servicetype === "lunch" || 'dinner'){ update({with new inserted data}) }else if(data doesn't match){ ref('meals').set({createNewNode}) }
Advertisement
Answer
The Firebase databases implement fairly limited query support. To expand that you often have to:
- Expand/modify your data model to allow the query you want
- Do part of your filtering in either client-side code, or in other systems (such as a dedicated full-text search engine).
There is no way to implement your conditions in a query on the Realtime Database, since:
- It only supports a single condition per query.
- It doesn’t support OR conditions.
You can sometimes combine multiple AND conditions into a single query, by adding a synthetic property to your data, such as "dates_serviceId": "..._..."
. With such a property in place, you can then query for ref.orderBy("dates_serviceId").equalTo("myDate_myServiceId")
.
To be able to query on nodes that have either lunch or dinner service, you’d have to expand your data model to explicitly identify such nodes, for example by adding a "lunch_or_dinner": true
property to them. With such a node, you can then query: ref.orderBy("lunch_or_dinner").equalTo(true)
By combining these two approaches, you could even create a single property for the entire query (dates_serviceId_lunch-or-dinner
), although I must admit that is becoming a bit overly specific even to my taste.