Retrieve first child value of parent value in Firebase realtime database - javascript

I'm working on a project that requires me to update a UI based on how many values exist in the database. For instance, when 2 child values are created, the UI updates to contain two boxes.
Currently, my code determines how many child objects exist;
database.ref("parent").on('value', displayValue);
function displayValue(c){
total = c.numChildren()
}
From here, I create how ever many elements, based on this number. My problem however, is how to get the initial child name, in this case, "child1" to update elements such as the title text.
Is there a way to pull these values based off an index, like in a javascript array array[index]?

The Firebase Realtime Database API does not have a way to access child nodes by their index. The only way to pull a child by index, is by loading all children into an array in your code, and then access them by index there.
If you want to iterate over all the child nodes in your snapshot, you can do:
database.ref("parent").on('value', (snapshot) => {
snapshot.forEach((child) => {
console.log(child.key); // "child1", "child2"
console.log(child.child("data").val()); // "123", "123"
});
}
If you want to update a specific child, you specify the keys for the entire path. For example:
database.ref("parent").child("child1").child("data").set("456")
Or a bit shorter:
database.ref("parent/child1/data").set("456")

Related

How to update element of any particular index in an array in MongoDb using mongoose in Node.js

Hi I tried to update the element at a particular index in an array but I'm not able to update it. It is updating the entire array. Not able to figure out how to update any particular index which is being passed by user. Let say user pass index from frontend as 1 then only the element at index 1 in appointment array gets updated not other.
Let say I have a schema in which I have Data who's type is array and default value is as shown below or anything in the same format.
Data: {
type: Array,
Default: ["0","1","0"]
}
Whenever I'll create a user then Data field will contain these default values, But now I want to update the value at index 1 of Data array of any user created.
I tried findByIdAndUpdate method but I don't know what to pass in set property. If I'm passing this {$set: req.body} and In postman I'm giving any value of Data then obviously it is updating Data array but I want to update value at any index how should I do that. What changes I have to make in {$set : }? Or any other method for that? Thanks in advance.
Waiting for any help or suggestions. Thanks

Firebase retrieve a document based on grandchild's value which is a collection [duplicate]

This question already has an answer here:
Firebase query if child of child contains a value
(1 answer)
Closed 1 year ago.
Is there a way to Query a collection which is a grandchild in firebase?
Current firebase structure:
{
products: {
"dfwojozijowjfoije": {
"barcodes": ["12345", "5678"],
"productName": "someProduct"
},
"sdafsdasdfasdfadsf": {
"barcodes": ["99999", "88888"],
"productName": "someProduct2"
}
}
}
Current Query that I use:
await firebase
.database()
.ref('products')
.orderByChild('barcodes')
.equalTo('88888')
.on('value', snapshot => {
setProductName(snapshot.val())
}
)
There is no way in a Firebase Realtime Database query to check for the existence of a value in an array. If you're trying to do this, it typically means that your data structure is actually not an array, but a set.
Since a set data type doesn't exist, you can't store it in Firebase natively though. The closest equivalent is not an array though, but a map like this:
"barcodes": {
"12345": true,
"5678": true
}
This may look a bit weird at first, but it has the exact properties that you're typically looking for in a set: the values (that are now keys) are by definition unique in the parent node, and you can test for the presence of a specific value/key.
Unfortunately, you still won't be able to query on this structure, as you can only define indexes on keys that you know, and I'm assuming that the barcodes are a rather infinite set of values.
So instead you'll have to define an inverted data structure, as I've explained here: Firebase query if child of child contains a value

ReactJS : Trying to print index of my array objects- which should change dynamically if i delete elements

Im building whats basically a todo list app right now, for learning reactjs.
this is my initial state
const [listx,setlistx] = useState(
[
{id:0,flavor:'strawberry',qty:'5'},
{id:1,flavor:'Vanilla', qty:'3'},
{id:2, flavor:'butterscotch', qty:'2'}
]
);
I basically want to render each element as a numbered list, but cant utilize the index for this. used map to pass data to a component .
{
listx.map(itemx =>(
key={itemx.index}
id={itemx.id}
It dosn't recognise key but prints id for the initial 3 elements, i could increment and add the id field for each element but it will remain static if i delete an element (right?)
one more thing i tried was calling a useEffect hook which did allow me to console.log the index of newly added element (which i strangely wasnt able to, otherwise) but i couldnt access any of the other methods from useEffect when i tried to update the state that way.
i also wrote a function with arr.findIndex() but it only returns index after i add the element, and i cant seem to access an element using
newID=findIndex(flavor,qty);
setlistx(listx[newID].id= newID;
i hope i made the problem clear enough
it doesn't recognise index because you have no index in your objects
{id:2, flavor:'butterscotch', qty:'2'}
but you can use id for key if it will be unique
listx.map(itemx => (
key={itemx.id}
id={itemx.id}
)
if you want to delete an element I would use filter
listx.filter(id => id !== idYouAreFilteringFor)
then it will rerender the list without the deleted one
If i understand correctly you want to use index instead of id as it is static and facing issue with delete?
In array map function we have 2nd arg is for index
listx.map((itemx, index) => (...))
But in react for key I would suggest not use index. For key i would suggest use id instead of index. Key is used in react for rendering performance purpose. For key you can use some unique id which will not keep changing. In your example id is not keep changing. If you will use index which will keep change if you delete item
Instead of static hard coded id i would suggest use uuid
And to delete element you can use filter method to delete element and set newly generated array to setlistx like below
say example you call handleDelete method on delete icon click then,
const handleDelete = (id) => {
setlistx( oldlistx => oldlistx.filter(item => item.id !== id));
}

How can I update an object inside of an array in firestore?

I would like to update the completed property of an object in an array in Firestore, but I have no idea how to reach that specific element in the array. The image will show the structure.
I have come up this far but don't know how to choose, for example, item 1 in the array. I was thinking of using its ID (it has an id property) but don't know how to get there.
const businessRef = db.collection('approvedBusinesses').doc(businessId)
try {
businessRef.update({
[`bookings.${currentDate} ????? `]: true // what to add after currentDate?
})
By the way, this is how the array was created (and how other objects are pushed to it)
const bookingObj = {
carro: 'PASSA_CARRO',
completed: false,
userId: userObject.uid,
}
businessRef.update({
[`bookings.${currentDate}`]: firebase.firestore.FieldValue.arrayUnion(bookingObj),
})
Firestore does not have an operation that allows you to update an existing item in an array by its index.
To update an existing item in the array, you will need to:
Read the entire document into your application.
Modify the item in the array in your application code.
Write back the entire array to the document.
I'm pretty sure this has been asked before, so let me see if there's an answer with an example.
Also see:
How to remove an array element according to an especific key number?
Simple task list ordering - how to save it to Firebase Firestore?
How to update only a single value in an array
How to update an "array of objects" with Firestore?

React list with no keys

I have an array of number that I wish to render in a tabular form. The array is returned from an API call, not generated by my app.
The data may change but is unlikely to do so, and in any case there are only twenty odd values, so re-rendering the whole table is not really a problem.
A simple data.map(value => <td>{value}</td> should do it.
But I keep getting an Each child in an array or iterator should have a unique "key" prop. warning. Is there any way that I can tell React that there is no key and that I wish it to re-render the whole table if anything changes.
Alternatively, is there any way that I can generate a unique key for each entry? The data items are not guaranteed to be unique.
I should add that I understand what keys are for and why they are useful, but in this instance I do not have any and the easiest thing would be not to use them, since there is unlikely to be a re-render.
You can use the index as the key. I think its worth reiterating that using the index as the key only works fine in the very specific scenario that the OP is facing.
This is particularly annoying when requirements change and all of sudden the list is being modified. This shows up as items not being updated during the render because the item updated has the same key (the index), its value is different, but react only cares about the key.
In cases where your data has no unique key. You should use some function that generates a unique id for each item. A simple version of that function just increments a global counter:
// Declared globally (as in attached to window object or equivalent)
var myuniqueidcounter = 0;
function uniqueId() {
myuniqueidcounter += 1
return myuniqueidcounter;
}
// Do this in the props change or whereever your data gets passed in
let keyedData = data.map(value => Object.assign(value, { Id: uniqueId() });
// In render
data.map(value => <td key={value.Id}>{value}</td>
That way, on multiple render calls, the ids returned are always unique. We assign the key when we get the data to avoid having to re-render the entire list on each call to render().
However, this case is actually pretty rare as you can usually find some combination of the backing data that will produce a unique key for each entry.
If you do go index-as-key
This article lists 3 conditions that should be met when choosing index-as-key approach that I think is a good check list:
The list and items are static–they are not computed and do not change;
The items in the list have no ids;
The list is never reordered or filtered.
data.map((value,index) =>{
<td key={index}>{value}</td>}
)
or
data.map((value,index) =>{
let i = Math.floor(Math.random() * 1000+1)
<td key={i}>{value}</td>}
)
You can use index as your key as it is unique each time
Based on the question asked, it might be worth saying that there is an another solution to this that doesn't use keys:
e.g. The following will complain about not having unique keys:
React.createElement('div', {}, [<span>1</span>, <span>2</span>]);
However, the following renders all children with no problems (This is what JSX transformed to JS looks like for nodes with multiple children):
React.createElement('div', {}, <span>1</span>, <span>2</span>);
So if you have e.g. a smallish list of generated react element fragments and unique keys don't offer and advantage in your situation, you can do:
React.createElement.apply(null, ['div', {}, ...elementList])
Notes:
elementList is passed as arguments to React.createElement which might be an issue if the list is huge.
It will re-render all the children with each render.
Using unique keys is generally the recommended approach, and is more performant for re-rendering.
However there are occasions where you just want to render in a single shot and don't care about re-rendering, or the data is not structured in a way that you can make good use of unique keys. You can use this as a work-around if you really need to.

Categories

Resources