Edit in JSFiddle

function runExample(demoUrl) {
    "use strict";
    
    var uid = null, room = null, submitted = false, sub = null, members = {}, userName;
    var ref = new Firebase(demoUrl);
    var $inp = $('input[name=data]');
    var $join = $('#joinForm');
    
    // handle input and form events
    $('#chatForm').submit(processForm);
    $inp.on('keyup', _.debounce(countChars, 50));
    $('#login').click(authenticate);
    $('a[href="#logout"]').click(logout);
    $('a[href="#leave"]').click(leaveRoom);
    $join.submit(joinRoom);
    
    function authenticate(e) {
        e.preventDefault();
        ref.authWithOAuthPopup('github', function(err, user) {
            if (err) {
                console.log(err, 'error');
            } else if (user) {
                // logged in!
                uid = user.uid;
                console.log('logged in with id', uid);
                $('#login-layer').hide();
                ref.child('room_names').once('value', buildRoomList);
            } else {
                // logged out
                $('#login-layer').show();
            }
        });
    }
    
    function logout(e) {
       e.preventDefault();
       ref.unauth();
    }

    // create option tags in our room select
    function buildRoomList(snap) {
        var $sel = $('select').empty();
        snap.forEach(function (ss) {
            $('<option />')
                .prop('value', ss.name())
                .text(ss.val())
                .appendTo($sel);
        });
        pickRoom();
        $sel.change(pickRoom);
    }

    // when the select is updated, load that room's messages
    function pickRoom() {
        roomOff();
        $('#chatForm').hide();
        var roomId = $('select').val();
        
        // see if we need to join or if we are already a member
        // by trying to load the list of members
        getMembers(roomId).then(loadRoom, showJoinForm);
    }
    
    function getMembers(roomId) {
        return $.Deferred(function(def) {
           // try to read the room's members, if we succeed
           // then we are a member
           ref.child('members').child(roomId)
           .once('value', function(snap) {
               members = snap.val() || {};
               if( !members.hasOwnProperty(uid) ) {
                  def.reject();
               }
               else {
                  setName(members[uid]);
                  def.resolve();   
               }
           }, def.reject);
        });
    }
    
    function showJoinForm() {
        console.log('showJoinForm');
       var $ul = emptyRoom();
       $('<li>You are not a member of this room</li>').appendTo($ul);
       var $li = $('<li />').append($join.show()).appendTo($ul);
    }
    
    function joinRoom(e) {
       e.preventDefault();
       var roomId = $('select').val();
       var name = $(this).find('input').val();
        if( name ) {
            setName(name);
            ref.child('members').child(roomId).child(uid).set(name, function(err) {
                if( err ) { log(err, 'error'); }
                else {
                   getMembers(roomId).then(loadRoom, result);   
                }
            });
        }
        else {
           log('Enter a name', 'error');   
        }
    }
    
    function leaveRoom(e) {
       e.preventDefault();
       roomOff();
       var roomId = $('select').val();
       ref.child('members').child(roomId).child(uid).remove(pickRoom);
    }
    
    function roomOff() {
       if( room ) { 
            // stop listening to the previous room
            room.off('child_added', newMessage);
            room.off('child_removed', dropMessage);
        }   
    }
    
    function loadRoom() {
        emptyRoom();
        $('#chatForm').show();
        room = ref.child('messages').child($('select').val()).limit(100);   
        room.on('child_added', newMessage);
        room.on('child_removed', dropMessage);   
    }
    
    function emptyRoom() {
        $join.detach();
        return $('ul.chatbox').empty();
    }
    
    function setName(name) {
       userName = name;
       members[name] = name;
       $('#chatForm').find('button').text('Send as '+name);
    }
    
    // create a new message in the DOM after it comes
    // in from the server (via child_added)
    function newMessage(snap) {
        var $chat = $('ul.chatbox');
        var dat = snap.val();
        var txt = members[dat.user] + ': ' + dat.message;
        $('<li />').attr('data-id', snap.name()).text(txt).appendTo($chat); 
        $chat.scrollTop($chat.height());
    }
    
    // remove message locally after child_removed
    function dropMessage(snap) {
        $('li[data-id="'+snap.name()+'"]').remove();
    }

    // print results of write attempt so we can see if
    // rules allowed or denied the attempt
    function result(err) {
        if (err) {
            log(err.code, 'error');
        } else {
            log('success!');
        }
    }

    // post the forms contents and attempt to write a message
    function processForm(e) {
        e.preventDefault();
        submitted = true;
        var val = $inp.val();
        $inp.val(null);
        if (!userName) {
            log('No username :(', 'error');
        } else {
            room.ref().push({
                user: uid,
                message: val,
                timestamp: Firebase.ServerValue.TIMESTAMP
            }, result);
        }
    }
        
    // tell user how many characters they have entered
    function countChars() {
        var len = $(this).val().length;
        if( len || !submitted ) {
            var style = len >= 50 ? 'error' : 'note';
            log(len + ' characters', style);
        }
        return true;
    }

    // print write results
    function log(text, style) {
        delayedClear();
        var $p = $('p.result').removeClass('error note success');
        style && $p.addClass(style);
        $p.text(text);
    }

    var to;

    // clear write results after 5 seconds
    function delayedClear() {
        to && clearTimeout(to);
        to = setTimeout(clearNow, 5000);
    }

    // clear write results now
    function clearNow() {
        $('p.result').text('');
        to && clearTimeout(to);
        to = null;
        submitted = false;
    }

}


// Dependencies used in this fiddle:
// code.jquery.com/jquery-2.1.0.min.js
// cdn.firebase.com/js/client/2.0.4/firebase.js
// cdn-gh.firebase.com/demo-utils-script/demo-utils.js
// cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js
//
// This line creates a unique, private Firebase URL 
// you can hack in! Have fun!
$.loadSandbox('web/usec/example', 'web/usec/example').then(runExample);