Throttle messages by user id

Ensure at least X seconds between messages to throttle activity

by Firebase

HTML

<script src="https://cdn.firebase.com/js/client/2.2.9/firebase.js"></script>
<h3>Firebase Template</h3>

<p>My ID: <span id="myid"></span></p>
<p><a href="https://gist.github.com/katowulf/00a4ec40df1552d01c7f" target="_blank">view security rules</a></p>
<button disabled="disabled">add record</button> <span id="time"></span>

<pre id="data"></pre>

CSS

pre {
    padding: 20px;
    font-size: 16px;
    line-height: 20px;
    background-color: #fafafa;
    border: 1px solid #999;
    display: block;
    border-radius: 10px;
    white-space: pre-wrap;
    /* css-3 */
    white-space: -moz-pre-wrap;
    /* Mozilla, since 1999 */
    white-space: -pre-wrap;
    /* Opera 4-6 */
    white-space: -o-pre-wrap;
    /* Opera 7 */
    word-wrap: break-word;
    /* Internet Explorer 5.5+ */
}
#time, .error {
    color: red;
}

JavaScript

var fb = new Firebase("https://kato-sandbox.firebaseio.com/throttled");
var userId; // my auth.uid
var data = {
    sender: null, // set after login
    timestamp: null, // set during callbacks
    message: 'hello world'
};

// authenticate
fb.authAnonymously(function (err, user) {
    if (err) {
        logError(err);
    } else if (user) {
        userId = user.uid;
        data.sender = userId;
        $('#myid').text(user.uid);
        $('button').prop('disabled', false);
    }
});

$('button').click(function () {
    // run our create routine
    createRecord(data, function (recordId, timestamp) {
        log('created record ' + recordId + ' at time ' + new Date(timestamp));
    });
    timeDown();
});

// updates the last_message/ path and returns the current timestamp
function getTimestamp(next) {
    var ref = fb.child('last_message/' + userId);
    ref.onDisconnect().remove();
    ref.set(Firebase.ServerValue.TIMESTAMP, function (err) {
        if (err) { logError(err); }
        else {
            ref.once('value', function (snap) {
                next(snap.val());
            });
        }
    });
}

function createRecord(data, next) {
    getTimestamp(function (timestamp) {
        // add the new timestamp to the record data
        data.timestamp = timestamp;
        console.log('creating record', data);
        var ref = fb.child('messages').push(data, function (err) {
            if (err) { logError(err); }
            else {
               next(ref.name(), timestamp);
            }
        });
        ref.onDisconnect().remove();
    })
}

var to;
function timeDown() {
    if( to ) { return; }
    var i = 5;

    function fn() {
        if (i === 0) {
            clearTimeout(to);
            to = null;
            $('#time').text('');
        } else {
            $('#time').text(i--);
        }
    }
    to = setInterval(fn, 1000);
    fn();
}

function logError(err) {
    console.error(err);
    $('#data').addClass('error');
   ...