Retornos de chamada do Firebase e AngularJS

Estou aprendendo AngularJS em conjunto com o Firebase. Eu estou realmente lutando com oon retorno de chamada do Firebase e tentando atualizar o$scope...

$apply already in progress <----

    var chat = angular.module('chat', []);
   chat.factory('firebaseService', function ($rootScope) {
  var firebase = {};
  firebase = new Firebase("http://gamma.firebase.com/myUser");
  return {
    on: function (eventName, callback) {
      firebase.on(eventName, function () {  
        var args = arguments;
        $rootScope.$apply(function () {
          callback.apply(firebase, args);
        });
      });
    },
    add: function (data) {
      firebase.set(data);
    }
  };
});

chat.controller ('chat', function ($scope, firebaseService) {
    $scope.messages = [];
    $scope.username;
    $scope.usermessage;              
    firebaseService.on("child_added",function(data){        
        $scope.messages.push(data.val());       
    });
    $scope.PushMessage = function(){
        firebaseService.add({'username':$scope.username,'usermessage':$scope.usermessage});   
    };
});

Se eu pegar o$rootscope.$apply então funciona como esperado, mas não atualiza o DOM no carregamento da página.

Obrigado!

ATUALIZAR

Solução 1 - Remova o$rootscope.$apply no serviço e injectar e aplicar o$timeout para o controlador:

firebaseService.on('child_added',function(data){        
    $timeout(function(){
        $scope.messages.push(data.val());                       
    },0);
});

Solução 2 - Implemente um método "SafeApply" (graças aAlex Vanston):

$scope.safeApply = function(fn) {
        var phase = this.$root.$phase;
        if(phase == '$apply' || phase == '$digest') {
            fn();
        } else {
            this.$apply(fn);
        }
    };

Embora ambos funcionem e não tenham muito código, sinto que são muito hacky. Não há alguma maneira Angular oficial para lidar com retornos de chamadas assíncronos?

Outro grande exemplo que encontrei para uma situação semelhante:HTML5Rocks - AngularJS e Socket.io

questionAnswers(1)

yourAnswerToTheQuestion