Sorting Firebase Data Based on Child Values - javascript

I'm trying to sort my Firebase query by the timestamps on each post child. Instead, I'm just getting the data as it's stored in the database, unsorted. I'm using the firebase npm package.
The data is structured as followed:
posts
-Lsx-tFbXe83gANXP3TD
-timestamp: 1466171493193
-Lsx-sWzXe83gANWNM3R
-timestamp: 1466171493111
Here is my javascript code that I wrote using: https://firebase.google.com/docs/database/web/lists-of-data
firebase.database()
.ref("posts")
.orderByChild("timestamp")
.on("value", function(snapshot) {
_this.setState({
posts: Object.values(snapshot.val()),
loading: false
});
});
Thanks in advance!

The snapshot you get back contains three pieces of information about the child nodes that match your query:
The key
The value
Their relative position to each other
As soon as you call snapshot.val() all information about ordering is lost, since a JSON object can only contain keys and values.
To maintain the order, you'll want to convert the information to an array:
var values = [];
snapshot.forEach(function(child) {
values.push(child.val());
})

Related

"Bulk" Updating with Postgres DB and JS/Knex/Express Question

I have an update endpoint that when an incoming (request) contains a site name that matches any site name in my job site's table, I change all those particular DB entries status to "Pending Transfer" and essentially clear their site location data.
I've been able to make this work with the following:
async function bulkUpdate(req, res){
const site = req.body.data;
const data = await knex('assets')
.whereRaw(`location ->> 'site' = '${site.physical_site_name}'`)
.update({
status: "Pending Transfer",
location: {
site: site.physical_site_name,
site_loc: { first_octet: site.first_octet, mdc: '', shelf: '', unit: ''} //remove IP address
},
//history: ''
}) //todo: update history as well
.returning('*')
.then((results) => results[0]);
res.status(200).json({ data });
}
I also want to update history (any action we ever take on an object like a job site is stored in a JSON object, basically used as an array.
As you can see, history is commented out, but as this function essentially "sweeps" over all job sites that match the criteria and makes the change, I would also like to "push" an entry onto the existing history column here as well. I've done this in other situations where I destructure the existing history data, and add the new entry, etc. But as we are "sweeping" over the data, I'm wondering if there is a way to just push this data onto that array without having to pull each individual's history data via destructuring?
The shape of an entry in history column is like so:
[{"action_date":"\"2022-09-06T22:41:10.232Z\"","action_taken":"Bulk Upload","action_by":"Davi","action_by_id":120,"action_comment":"Initial Upload","action_key":"PRtW2o3OoosRK9oiUUMnByM4V"}]
So ideally I would like to "push" a new object onto this array without having (or overwriting) the previous data.
I'm newer at this, so thank you for all the help.
I had to convert the column from json to jsonb type, but this did the trick (with the concat operator)...
history: knex.raw(`history || ?::jsonb`, JSON.stringify({ newObj: newObjData }))

Retrieve an child value and compare using firebase by javascript

const uid = firebase.auth().currentUser.uid;
var query = firebase.database().ref("/user/").child(user.uid).orderByChild("l1").equalTo("bought ")
query.on("value", function(snapshot) {
var lg1=document.getElementById("lg1");
var lg2=document.getElementById("lg2");
var blg=document.getElementById("blg");
lg2.style.display=" none";
lg1.style.display="block";
blg.style.display="block";
});
I am comparing a child data in firebase realtime database and disable enable display using the snapshot function but it's not working I tried and research a lot but I couldn't find a perfect solution.
Any ideas on how to proceed above code?
Here is the screenshot of my firebase realtime database
Firebase queries work on the list of direct child nodes under the path that you query.
Since your query runs on /user/$uid, the nodes the query considers are email, l1, points and uid. For each of those it then looks for a child property l1 and compares the value to what you specified. But none of these four nodes has an l1 property.
If you want to be able to search the child nodes of /user/$uid for their l1 property, you need an extra level in the JSON, which is typically generated by calling push() as shown in the documentation on adding nodes to a list. So your JSON would become
user: {
"$uid": {
"$pushid": { // 👈 new
email: "...",
l1: "...",
points: ...,
uid: "...",
}
}
}
With that structure your query will work.

How can i compare user inputs to my firebase and make it return only the ones that are exact

I have too much data to sort on javascript so i'm trying to make firebase do the sorting and only send the data back with the correct info. As an example if a user inserts the city of "Tedrow" i only want the firebase to bring back array with the "LOCCITY" value of "Tedrow" I also want it to search each number as show in nested firebase pic 2
nested firebase pic
nested firebase pic 2
I've tried using .child to get into nested firebase but that didn't seem to work.
firebase
.database()
.ref()
.child('features')
.once('value', function (featuresSnapshot) {
for (var towerId in featuresSnapshot.val().features) {
featuresSnapshot
.child([towerId])
.child("properties")
.forEach(function (openTicketSnapshot) {
console.log(openTicketSnapshot.key);
var val = openTicketSnapshot.val();
console.log(val.LOCCITY);
});
}
});
I'm expecting to see array pop up with the "LOCCITY": "tedrow"
Instead nothing is showing, no errors or anything

How to obtain a record of a node, according to the value of a property, firebase?

I currently have the following node:
Basically what I want is to search the registry by the uid parameter. What I can not understand is that they tell me that I should not do it by means of a query, so what would be the other way? I have tried with the following:
firebase
.database()
.ref('nuevosUsuario')
.child(user.uid)
.once('value')
.then(snapshot =>
console.log(snapshot.val())
);
pero me imprime en consola null
Thank you in advance, I'm new to firebase.
You JSON structure stores user information, where it stores the information for each user under a so-called push ID (a key generated by calling push() or childByAutoId()). You're trying to query this structure to find the user based on their UID, which is stored in a property for each user. The only way to do this is by using a database query, like:
firebase.database()
.ref('nuevosUsuario')
.orderByChild("uid")
.child(user.uid)
.once('value')
.then(snapshot => {
snapshot.forEach(userSnapshot => {
console.log(snapshot.val())
});
});
You need to perform a loop here, since there may be multiple nodes that have the correct value for their UID property.
If there can logically be only one node for each user under nuevosUsuario, it is better to store the user information under the user's UID as a key, instead of using a push ID.
So you'd get a structure like:
"nuevosUsuario": {
"SYFW1u808weaGEf3fW...": {
"appellido": "PRUEBA",
"correo": "..."
...
}
}
This has a few advantages:
There can only be one child node for each user, since keys are by definition unique in a collection.
You can now get the user given their UID without a query, which is both faster and simpler in code. As in: the code in your question would work for this structure.

firebase simple - data structure questions

I have been reading a little about how to structure your firebase database and i understand that you need to split your data into pieces so you don't forced the client to download all of the 'users' data.
So in this example you will get all the users data when you write
ref.('users').once('value', function(snap)...
/users/uid
/users/uid/email
/users/uid/messages
/users/uid/widgets
but what if you specifically write the path to the location instead like
ref.('users/uid/email').once('value', function(snap)...
Will you still get all the users data or only the data in email ?
In firebase, you set the ref to be the reference for your database (the whole database) and then you got methods to iterate through each piece of data of your database object, hence, a good practice is to set all your database as the ref and then work from there to go through what you want to go.
// will select the whole db
const firebaseRef = firebase.database().ref();
// will select the whole app object of your db
const firebaseRef = firebase.database().ref().child('app');
// will select the whole users object of your db
const firebaseRef = firebase.database().ref().child('app/users');
So, it is a good practice to set a variable like firebaseRef to be your whole firebase db and then iterate from there.
Now, if you write:
firebaseRef.child(`users/${uid}/email`).once('value').then(snapshot => {
console.log('User email: ', snapshot.val());
}, e => {
console.log('Unable to fetch value');
});
Yes, you will get what you're asking, but you need to use the child method to get to the objects of your firebase ref.

Categories