Firebase does not support queries with a dynamic parameter, such as "two hours ago". It can however execute a query for a specific value, such as "after August 14 2015, 7:27:32 AM".

That means that you can run a snippet of code periodically to clean up items that are older than 2 hours at that time:

var ref = firebase.database().ref('/path/to/items/');
var now = Date.now();
var cutoff = now - 2 * 60 * 60 * 1000;
var old = ref.orderByChild('timestamp').endAt(cutoff).limitToLast(1);
var listener = old.on('child_added', function(snapshot) {
    snapshot.ref.remove();
});

As you'll note I use child_added instead of value, and I limitToLast(1). As I delete each child, Firebase will fire a child_added for the new "last" item until there are no more items after the cutoff point.

Update: if you want to run this code in Cloud Functions for Firebase:

exports.deleteOldItems = functions.database.ref('/path/to/items/{pushId}')
.onWrite((change, context) => {
  var ref = change.after.ref.parent; // reference to the items
  var now = Date.now();
  var cutoff = now - 2 * 60 * 60 * 1000;
  var oldItemsQuery = ref.orderByChild('timestamp').endAt(cutoff);
  return oldItemsQuery.once('value', function(snapshot) {
    // create a map with all children that need to be removed
    var updates = {};
    snapshot.forEach(function(child) {
      updates[child.key] = null
    });
    // execute all updates in one go and return the result to end the function
    return ref.update(updates);
  });
});

This function triggers whenever data is written under /path/to/items, so child nodes will only be deleted when data is being modified.

This code is now also available in the functions-samples repo.


I have a http triggered cloud function that deletes nodes, depending on when they were created and their expiration date.

When I add a node to the database, it needs two fields: timestamp to know when it was created, and duration to know when the offer must expire.

enter image description here

Then, I have this http triggered cloud function:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();

/**
 * @function HTTP trigger that, when triggered by a request, checks every message of the database to delete the expired ones.
 * @type {HttpsFunction}
 */
exports.removeOldMessages = functions.https.onRequest((req, res) => {
    const timeNow = Date.now();
    const messagesRef = admin.database().ref('/messages');
    messagesRef.once('value', (snapshot) => {
        snapshot.forEach((child) => {
            if ((Number(child.val()['timestamp']) + Number(child.val()['duration'])) <= timeNow) {
                child.ref.set(null);
            }
        });
    });
    return res.status(200).end();
});

You can create a cron job that every X minutes makes a request to the URL of that function: https://cron-job.org/en/

But I prefer to run my own script, that makes a request every 10 seconds:

watch -n10 curl -X GET https://(your-zone)-(your-project-id).cloudfunctions.net/removeOldMessages

In the latest version of Firebase API, ref() is changed to ref

var ref = new Firebase('https://yours.firebaseio.com/path/to/items/');
var now = Date.now();
var cutoff = now - 2 * 60 * 60 * 1000;
var old = ref.orderByChild('timestamp').endAt(cutoff).limitToLast(1);
var listener = old.on('child_added', function(snapshot) {
    snapshot.ref.remove();
});