Reputation: 453
I face the problem that I have a list of keys inside my firebase database and I want to retrieve one random key out of it, without downloading all keys and selecting one in my own app. Downloading all keys with for example .once()
is a big no go, especialy because I may up end with 10.000+ keys in the future and I dont want my firebase bills to explode, Im still a student with no budget at all.
I already researched this topic and found following answer for my question.
The problem with this is, that I can not use limitToFirst()
and also limitToLast()
in the same query, else I get following error:
[Unhandled promise rejection: Error: Query.limitToLast: Limit was already set (by another call to limit, limitToFirst, or limitToLast).]
Also other people face the same problem like me and I generaly see that this question always gets much views but rather poor answers which are, like apperently in the case I mentioned earlier outdated, or just not for usage in Javascript and React-Native.
Additional informations: I have a counter for my keys so I know at every time how many keys are stored inside my database. Following picture shows my database entirely:
This is the part of my code which shows the mentioned error:
const numberOfUsers = await firebase.database().ref("usercounter").once("value").then(snapshot => {
return(snapshot.val()); //retrieve numbers of users from "usercounter"
});
const randomIndex = Math.floor(Math.random() * numberOfUsers) + 1; //"generating random number, excluding 0"
var ref = firebase.database().ref('users'); //ref to my users keys
await ref.limitToFirst(randomIndex).limitToLast(1).once('value').then(DataSnapshot =>
{
//This is the query that does not work at all.
console.log(DataSnapshot.val())
});
Incase there is a way to overcome that problem, please let me know.
Upvotes: 0
Views: 816
Reputation: 7408
I would solve that problem this way:
Create for each list element a value with the field name id
or some other you want. It should be a simple integer. Idealy incrementaly growing with the list. You could use the counter to increase the value each time you add an element.
When trying to get a random element from the list first get a random integer between 0 and the total count of all elements. Then use this query to get a single random element:
firebase.database().ref("users").orderByChild("id").startAt(randomNumber).limitToFirst(1);
Even if you don't hit the id
with the randomNumber
you would the neareas next element. This should be able to scale to any size.
The most diffictult part would be to optain the id
incrementaly without repeating them. I would use for that an cloud function that does it when an item is added. Even a combination with the counter would be interesting.
Upvotes: 2