Access nested value in Firebase Realtime Database - javascript

I'm a Firebase newbie and I would like to figure out how to access deep nested data in Realtime Database.
Let's suppose I have the following structure:
I would like to get the block of data in which location -> Id value corresponds to 3154380, (in this case is the second one)
How could achieve this ?

Just put the sub-path in .orderByChild and use .equalTo:
database().ref('reports').orderByChild('location/id').equalTo('3174380');
However, I will say, you should really look at flattening your data structure for best performance and usability in this environment.

Related

Auto generate sub database firestore

I have a firestore collection with a bunch of documents, each with plenty subfields. On a web page I need a list of a specific subfields from each document.
Currently I load the the entire database when you load the page and then loop through and get the wanted values. This uses way to many reads to get very little data.
Is there a way to solve this e.g. a autogenerated a collection that contains field from other collection in an array or something.
Many thanks in advance
Auto-creating such a subcollection with just the fields you need is a great way to reduce the bandwidth needed to load the data.
There is nothing built into Firestore to create those derived documents, but it's fairly easy to build something using Cloud Functions. Create a function that responds to a Firestore onWrite trigger, and write the subset of the data to its destination there. It's common to have a separate Cloud Function for each such use-case, and I regularly see projects with 100+ such functions.
I expect we'll also start seeing Firebase Extensions for this type of thing, but right now no-one seems to have built one.

Firebase get grandparent object from grandchild key

I try to retrieve all the grand parent objects when a grandchild key is matched. In the Firebase realtime database below, I have for example the sensor key "-LNVBiM1SGoAFvlMfi1V", and I need to retrieve with it all the orders objects where this key is found (04TBR7 in this example).
I know the database structure might not be perfect but there is no possibility to modify it for now.
I tried the following code but it is not right, I guess the equalTo is not working since it is an Object:
db.ref('/orders').orderByChild('sensors').equalTo(sensor_id).once('value', snapshot => {
// my snapshot is always empty ...
});
There is no way to use orderByChild("sensors") in the way you're trying, as it checks the value of the sensors property (not the key).
It's important to keep in mind that Firebase database queries work on a flat list of nodes. So you can search for a specific order property across all orders, and you can search sensors under a specific order. But you can not search across all sensors for all orders.
Since you say you can't modify the data structure, that unfortunately means you'll have to load the entire JSON and find the matching nodes client-side.
Also see:
Firebase query if child of child contains a value
Firebase Query Double Nested

How to get firebase data in inner node without the outer node name?

I want to read data from firebase, in the ref ("locations/{{someLocation}}/logs/{{someDevice}}")
but I do not know if exists a correct form to do, because I need to use ".on" to hear constantly all the devices changes, the problem is that I need to read all devices in logs in all locations, but I do not want another information, I just need information in logs or in the specific device, I know that I could reach that invoking one callback ".on" for each device, but I want a cleaner form to make it and in the documentation, there is no help for this.
maybe I could invoke a method like that
firebase.database("locations/{eachLocation}/logs/{eachDevice}").ref().on...
because I do not want all the devices, the problem is that I do not know if there is a form to make it thank you.
It sounds like you've nested your data too much. The Firebase documentation has explicit sections on avoiding nesting data and flattening data structures with hints on how to prevent this.
At first glance you'll need at least two top-level lists: locations and locationLogs. Under each you have the same keys as you have now, but the logs are now under /locationLogs/$key instead of under /locations/$key/logs. With that change you can get the logs for a location without getting the other data for that location.
If you don't know the location key, but don't want to get the logs for all locations, it sounds like you've nested another level too deep. Firebase queries work on a flat list of nodes, and can't search across multiple levels of unknown keys. If you want to search across all logs across all locations, you will need to keep a flat list of all logs. You can then tie each log back to its location, by adding the location ID to each log.
So that might lead to a structure of:
logs: {
"adjustableLight....1": {
locationId: "DTZB35",
date: 156...,"
...
}
}
What you're trying to do isn't supported by Realtime Database. There are no wildcard queries or placeholders. You must be able to build the full path to the node whose data you want to get.
Consider changing the structure of your data so that you can more easily find the nodes you want. It is common in nosql type databases to duplicate data into structures that are easier to query for a particular use case.

Are there any "lifecycle" events for Firebase Realtime Database?

While working with Firebase (the realtime database) I'd like to know the following about the objects in the database:
Whether an object exists at a path
When an object is created at a path
When an object is destroyed at a path
I can figure out some hacks for these. For example:
Subscribe to on('value') events and download the whole (often huge) object.
Create a separate "flag" value for each object in the database that gets modified when objects are created and destroyed.
Listen for 'child_added', 'child_removed', etc. on a particular field inside of an object, that has the same lifetime as the object.
These get the job done in some specific circumstances but are pretty arbitrary and don't scale well.
Is there a way to achieve the above without having to either download the whole object or else creating a bunch of "book-keeping" entries in the database?
It's common to duplicate data and add additional to your database to satisfy your expected queries, without accessing too much data. There aren't any hidden or secret operations - what you see in the documentation is your toolset. It sounds like you're doing the right things already.
Assuming the web SDK (browser perspective), realtime updates (.on) are the proper way to get this type of data. The data should not be huge - it's called the "Realtime Database" bcs it's not intended to store large filetypes such as images and videos.
Listen for value events
var starCountRef = firebase.database().ref('posts/' + postId + '/starCount');
starCountRef.on('value', function(snapshot) {
updateStarCount(postElement, snapshot.val());
});

Firebase database retrieving data from comma seperated list

I want to store the comma separated ids on a child node & how can I filter data as in sql we can use IN clause to fetch data any possibility in firebase to perform this kind of operation in firebase database.
Please suggest any possible solution for this.
Firebase Realtime Database doesn't have the equivalent of SQLs IN clause. It also doesn't have a way to find a substring in a value. So the data model you are looking to use, doesn't allow the use-case you want. As usual with NoSQL databases, the solution is to pick a data model that does allow your use-case..
The most likely cause I know for the structure you describe is to associate the child node with a bunch of categories. If that is your case, read my answer here for a proper data structure: Firebase query if child of child contains a value
This is one of the cases where the new Cloud Firestore database offers better querying support, since it recently added a feature to efficiently test if an array contains a certain value (video). If you're only just getting started with your project, you might want to check if Firestore is a better fit for your use-cases.

Categories