2

I am using this question as a reference, since it is very similar.

If I have a set of defined keys:

-Ke1uhoT3gpHR_VsehIv
-Ke8qAECkZC9ygGW3dEJ
-Ke8qMU7OEfUnuXSlhhl

and also know that they all do exist under a node (let's say /items), how would I query for them, while also listening for changes on those keys (aka not using myRef.once(value) but using myRef.on('value', snapshot => { ... })

I know this is possible:

var keys = [ 
  "-Ke1uhoT3gpHR_VsehIv",
  "-Ke8qAECkZC9ygGW3dEJ",
  "-Ke8qMU7OEfUnuXSlhhl"
];
var promises = keys.map(function(key) {
  return firebase.database().ref("/items/").child(key).once("value");
});
Promise.all(promises).then(function(snapshots) {
  snapshots.forEach(function(snapshot) {
    console.log(snapshot.key+": "+snapshot.val());
  });
});

but it is a static snapshot. Could it be possible to do the same while listening for changes?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Walter Monecke
  • 2,386
  • 1
  • 19
  • 52
  • What are you trying to accomplish? Because the `Promise.all()` in the linked answer was to ensure you can detect when all data has loaded. Since you indicate you want to use regular/`on()` listeners, what is the use-case for waiting for their values? – Frank van Puffelen Sep 25 '17 at 15:38
  • @FrankvanPuffelen The keys represent jobs that are showed in a feed. I would like that the jobs within the feed update in real time (lets say that the creator of the job updated the jobs time). – Walter Monecke Sep 25 '17 at 15:42
  • So that sounds like regular `on()` listeners would work and you don't need `Promise.all()`. The code in your question is a 1:1 copy from my answer you linked. Did you try attaching listeners with `on()` already? – Frank van Puffelen Sep 25 '17 at 15:44
  • Yes I attached it. I guess the only way to handle the `on()` listener is that you loop through the keys like so: `for (let i = 0; i < jobKeysArray.length; i++) { firebase.database().ref("/jobs/${jobKeysArray[i]}").on('value', snapshot => { // handle all incoming data }) }` Would this be the correct way to do it? Is it done in a single request? I guess I was expecting a way to store all the promises in an array and also to know once the first read like `Promise.all` was done. – Walter Monecke Sep 25 '17 at 16:03
  • Since `on()` doesn't return a promise, you can't use `Promise.all()` with it. But you can loop over all keys similar to the code you found and attach a regular `on()` listener. If that is causing problems, post the [code you wrote that reproduces that problem](http://stackoverflow.com/help/mcve) by editing the question. – Frank van Puffelen Sep 25 '17 at 18:57
  • @FrankvanPuffelen It is not causing problems but you can definitely see that one object arrives after the other, this means it is not made in one single request? – Walter Monecke Sep 26 '17 at 11:30
  • Requests are pipelined. See http://stackoverflow.com/questions/35931526/speed-up-fetching-posts-for-my-social-network-app-by-using-query-instead-of-obse/35932786#35932786 – Frank van Puffelen Sep 26 '17 at 15:19

1 Answers1

2

I also have been looking for this. So it seems it doesn't exist, simply because Firebase has an efficient connection it is not necessary to combine 'queries' for the sake of connection performance.

So you would end up setting on('value', ...) event listeners for all keys. The code you could write for that could look like this, based on the code fragment given in your question:

var keys = [ 
    "-Ke1uhoT3gpHR_VsehIv",
    "-Ke8qAECkZC9ygGW3dEJ",
    "-Ke8qMU7OEfUnuXSlhhl"
];
function itemUpdate(snapshot) {
    console.log(snapshot.key+": ", snapshot.val());
}
var ref = firebase.database().ref("/items/");
keys.forEach(function(key) {
    ref.child(key).on("value", itemUpdate);
});

Where the only improvements would be to define the callback function or else you would create as many callback functions as you have keys to listen on and second to place the ref in a var.

7ochem
  • 2,183
  • 1
  • 34
  • 42
  • What if the number of keys you were trying to listen to was large? Like, let's say you were trying to listen to all members of a group, and the group could have 100s of users. Would you suggest in this case making a key for the group and listening to the group key instead? – lnogueir Feb 17 '23 at 20:48
  • 1
    I don't think 100s of listeners is that much for the Firebase connection to handle. I haven't worked with group keys, but you can try if that works for you. It's quite hard though to process changes when setting a listener on a high level with the purpose of monitoring changes on a deeper level. IMO it's better to set listeners on the exact child elements instead. – 7ochem Feb 20 '23 at 14:15