Usando promises com Firebase

Imagem ilustrativa

As vezes precisamos esperar algo acontecer assincronamente para só então prosseguir, para isso usamos promises, no AngularJS podemos usar a diretiva $q para criar promessas.

Imagine que temos uma função .get que trás os dados do usuário no firebase, essa função está alocada em uma objeto Javascript:

var obj = {};

obj.get = function(email){
}

Precisamos criar uma promessa dentro dessa função com $q:

obj.get = function(email){

    // Cria um promisse
    var deferred = $q.defer();
}

Agora preparamos uma consulta que irá buscar pelo email do usuário no firebase:

obj.get = function(email){

    // Cria um promisse
    var deferred = $q.defer();

    // Consulta no DB
    var query = firebase.database()
                .ref('usuarios')
                .orderByChild('email')
                .equalTo(email)
                .limitToFirst(1);
}

Usamos a função .on para rastrear quando o firebase retornar a consulta:

obj.get = function(email){

    // Cria um promisse
    var deferred = $q.defer();

    // Consulta no DB
    var query = firebase.database()
                .ref('usuarios')
                .orderByChild('email')
                .equalTo(email)
                .limitToFirst(1);

    query.on('value', function(snapshot){

    });
}

Dentro dessa função, verificamos se achamos algo com snapshot.val(), se achou, nós ressolvemos a promessa devolvendo data, senão nós deferimos com deferred a promessa:

obj.get = function(email){

    // Cria um promisse
    var deferred = $q.defer();

    // Consulta no DB
    var query = firebase.database()
                .ref('usuarios')
                .orderByChild('email')
                .equalTo(email)
                .limitToFirst(1);

    query.on('value', function(snapshot){

        var data = snapshot.val();

        // Se achou
        if (data){
            deferred.resolve(data);
        }
        // Se não achou, resolve
        else{
            deferred.reject();
        }
    });
}

Por fim, devolvemos a promessa ao final, pois iremos agora chamar .get e tratar a promessa com .then:

obj.get = function(email){

    // Cria um promisse
    var deferred = $q.defer();

    // Consulta no DB
    var query = firebase.database()
                .ref('usuarios')
                .orderByChild('email')
                .equalTo(email)
                .limitToFirst(1);

    query.on('value', function(snapshot){

        var data = snapshot.val();

        // Se achou
        if (data){
            deferred.resolve(data);
        }
        // Se não achou, resolve
        else{
            deferred.reject();
        }
    });

    // Retorna o promisse
    return deferred.promise;
}

O bacana agora, é que toda vez que eu precisar trazer um usuário do Firebase, eu posso tratar de esperar o serviço responder para eu fazer algo usando .then:

var promisse = obj.get('diogo@diogo.com');

promisse.then(function(response){
    console.log('Promessa resolvida com sucesso!');
}, function(response){
    console.log('Promessa deferida!');
}

É isso, até a próxima!