Get random key from a real-time Firebase database

There aren't any functions in Firebase to get a random item from the real-time database so far. 😢

Let's assume that you have a dataset such as:

json
{
    "posts":{
        "key_1":{
            "title": "title",
            "message": "message",
            "timestamp": 4598878
        },
        "key_2":{
            "title": "title",
            "message": "message",
            "timestamp": 4598978           
        },
        ⋮
        ,
        "key_n":{
            "title": "title",
            "message": "message",
            "timestamp": 4698878  
        }
    }
}

If your dataset includes a timestamp, you could pick a random item:

javascript
import { db, get, limitToFirst, limitToLast, query, ref } from './Firebase'

// Let's assume that top-level await is allowed (ES2022) to beautify the explanation
// You get both first and the last element
let snapshot_1 = await get(query(ref(db, 'posts'), orderByChild('timestamp'), limitToFirst(1)))
let snapshot_2 = await get(query(ref(db, 'posts'), orderByChild('timestamp'), limitToLast(1)))

// Now you can get both timestamps
let timestamp_1 = Object.values(snapshot_1.val())[0].timestamp
let timestamp_2 = Object.values(snapshot_2.val())[0].timestamp

// At this point you can get a random value between both timestamps
let random = Math.random(Math.random * (timestamp_2 - timestamp_1 + 1) + timestamp_1)

// Finally, you can pick a random item 
let snapshot_random = await get(query(ref(db, 'posts'), orderByChild('timestamp'), startAt(random), limitToFirst(1)))

I don't have a timestamp. So, what?

You can include it by doing the following:

javascript
import { db, get, onValue, ref, runTransaction } from './Firebase'

const addTimestamp = () => {

    let now = Date.now()

    onValue(ref(db, 'posts'), snapshot => {

        Object.keys(snapshot.val()).forEach((key, i) => {

            runTransaction(ref(db, `posts/${key}/timestamp`), value => now + i)

        })

    }, { onlyOnce: true })

}

You could also add a unique value to each of your items (a counter).

Hi, I'm Erik, an engineer from Barcelona. If you like the post or have any comments, say hi.