Is it possible to add a ValueEventListener by going though an unknown child in firebase for android?
What I've tried so far is something like this:
reference
.child("data")
.child(/*unknown_key*/)
.orderByChild("contacts")
// etc...
Where at the "unknown_key" I've tried many options, such as "{placeholder}", "{*}" or "*"
This is somehow possible in Firebase Functions, by passing a generic node in the URL, such as https://myfirebaseproj.firebase.com/data/{any}/contacts
I know that I could just get the children under the data/ node and do some iterations, but this feels overkill to me, since the node could really be big and the cost is expontential.
Related
In an effort to reduce data transfer (since it's costing us a lot of money), we're in the process of updating our Firebase Realtime Database value listener to use child listeners. Since most of the fields don't change, and the ones that change most frequently we only care about in certain app states, using only child added and child removed listeners seems to fit the bill.
Adding listeners for just child_added and child_removed appears to work perfectly on web. And iOS seems to be set up that way as well, though I admittedly haven't tested there yet. Android, however, appears to require that we add one massive listener that will listen for child moved and child changed too.
Listening for these, to my understanding, mostly defeats the purpose of using the child listeners over the value listener. Since any time any of the child's data changes (most of which we don't care about most of the time), it will send the entire child's snapshot again. We're trying to avoid data transfer by only listening for added/removed and circumstantially specific child properties, but this requires we basically listen to all of it at all times? Is there another way to implement this, to get what I'm hoping for?
To summarize our object, we have:
parent
--child A
----child A property 1
----child A property 2
--child B
----child B property 1
----child B property 2
etc. And we want to know when a child is added or removed, but most of the time we don't care about keeping the child's properties updated and would prefer to avoid re-transferring that data. How is that accomplished on Android (using Java, specifically)? Thanks!
There is no difference between the data transferred for a ValueEventListener vs a ChildEventListener when they are used on the same query/path in the database.
If you only want to know when a child is added/remove, but not about their contents, consider adding an additional top-level branch to your tree, where you keep just the key of the child node and then true as its value.
In my project a wearos app communicates with a handheld mobile app using dataitems. My wearOS app sends data by placing and changing a data item in the data layer.
Before placing the item I want to load/get the item before potentially overwriting its content. I can recieve it using dataClient.getDataItems(). Yet to me this just seems not optimal, I wanna use dataClient.getDataItem(uri). In order to get the specific item I merely need the uri.
uri format: wear://<node_id>/<path>
The only thing I dont know is the node_id of my creator node. Through logging I have seen, that, even doe I create a new DataClient everytime, when I put a new item to data layer, the node id stays same. Yet I couldnt find a way to access the id.
I feel like there should be a simple function like getLocalNodeId() to get the missing uri part. Am I wrong?
No idear, why that took me so long to find:
var node_id = Tasks.await(getNodeClient(context).localNode).id
Suppose we would like to retrieve 15 random children from questions node having this database structured as below:
1. The first (intuitive and discussed) way of retrieving random children from Firebase is to retrieve the whole required parent node (questions as dataSnapshot) and then select some random children on the client-side. This method has been pointed out in many posts, like in this one here .
Obviously, this method has its downsides; for example when querying through a large sized parent node (e.g. over 10.000 children) retrieving such an amount every time would result in a huge bandwidth usage as well as a client side burden. (when we actually require only a small amount of children)
2. Moving on: another approach, as described here which uses an iterator somehow bypasses the whole client side burden, yet the huge bandwidth usage could still occur as we download the whole parent node every time.
3. An interesting approach is described in Tom's answer in this firebase discussion which proposes:
A hacky way of doing this would be to generate a random key and do a query with startAt().limit(1). I have a feeling this could hurt the performance of your firebase though, so this should not be an operation you perform often. We don't have a real random sample function.
This solution actually sounds pretty good, yet I am not sure how it would indeed impact my Firebase.
4. Another silly solution could actually be naming the question ids manually, so to speak, from 0 to N, therefore handling the random group of ids on the client side and retrieving the questions spot-on by knowing the actual name of nodes.
5. And lastly, I have come up with the following solution to which I ask if is more or less viable than the ones presented above: creating another parent containing the question ids only and when needed, one should retrieve this parent which is much "lighter" than questions parent . From there, I would have the specific random ids and I would only need to snipe for those children. To better understand my meaning, please check the below picture:
Now, from this method arises the following issue: is assigning (let's say) 15 eventListeners good practice? Could this actually slow up things? (Note: this applies to methods 3 and 4 as well)
And ultimately, which method is actually the optimal one when querying from a large database for some random children?
You can use the classic solution as I explained in this answer but if you are afraid of getting huge amount of data then use instead 15 listeners. There is nothing wrong in using listeners as long as you remove them according to the life-cycle of your activity. So, IMHO go ahead with 15 listeners.
We have 2 case here
case 1
If you want to grab all details of the random ids at once, then I suggest 1 listener to the parent node (get value of datasnapshot using pojo class).
case 2
If you want to get the details independently upon request then you will have to attach a listener to each (random id) that you want.
Concerning performance
Try to use only Listener For Single Value Events as they listen one time and then stop (better for performance).
Dont use Value Event Listener (because these listeners keep checking for changes and therefore bad performance as listeners increase).
EDIT
lets say you listened to (questions_ids) node, now you have access to the random id keys, store them in a String variable, and then inside the same listener add another listener to (questions) pointing to the id that you want to grab details
//first listen to question ids ref (the one with 15 ids)
question_ids_ref.addListenerForSingleValueEvent(...{
//grab the key of each (random id) and store in variable
String random_01=......;
//run another listener this time to questions ref
questions_ref.child(random_01).addListenerForSingleValueEvent(..{
//get details of random_01 and so on....
});
});
I need to measure the size/length of an element or list in Firebase but I don't need the real content.
Something like firebase.database().ref("users/").once("length" || "size").then(callback)
ps Javascript SDK
Firebase doesn't have a count operator, so the only way is to download all children or keep a separate <children>_count property in sync. The latter is not a trivial task (see my answer here for one approach and this example Cloud Function), so most often developers likely end up going with the downloads-too-much-data-but-is-trivial approach:
ref.child("messages").on("value", function(snapshot) {
console.log("There are "+snapshot.numChildren()+" messages");
})
A more efficient way to count the children would be to fire a REST call with shallow=true parameter, which will give you just the keys. See In Firebase, is there a way to get the number of children of a node without loading all the node data?
Also found a post which does it a different way...
Object.keys(users).length;
Post: Length of a JavaScript object
I would like to retrieve children on a specific node on my Firebase database.
However I don't want to pull down all of them, I'm only interested in a specific set for which I have the keys.
I know I can accomplish this by just retrieving all of the children and check for their KEYs when they come back, but I expect this particular node children to grow quite large, and doing this would be extremely inefficient.
I could also explicitly aim each children like this:
firebase.child(PARENT_NODE).child("objectId1").addValueEventListener(this);
firebase.child(PARENT_NODE).child("objectId2").addValueEventListener(this);
firebase.child(PARENT_NODE).child("objectId3").addValueEventListener(this);
But this doesnt feel "right", somehow. I would have to unsubscribe from three or more connections, I can see this getting messy quickly.
Is there a way to do something like:
firebase.child(PARENT_NODE).children(new String[] {"objectId1", "objectId2", "objectId3"}).addValueEventListener(this);
Thanks