15/04/2018 Development / java script

Esse macete aqui, poucos conhecem! Então eu vou passar o pulo do gato pra galera!!!

Quando se está trabalhando com firebase, pode ocorrer da sua tabela ser muito grande, tipo ter uns 90mil registros.

Isso vai onerar sua aplicacao, então, no caso é melhor fazer uma paginação.

Mas como faço pra pegar o total de itens do meu banco?

firebase.auth().currentUser.getToken().then(data => {

let auth = data;

fetch('https://SEUPROJETO.firebaseio.com/SUAREFERENCIA/.json?shallow=true&auth=' + auth).then(resp => { return resp.json(); }).then(data => { this.gridOptions.totalItems = Object.keys(data).length; console.log(Object.keys(data).length) });

});

E oque é esse auth?

auth é a chave de autenticacao, que indica que você pode realmente acessar os dados. Pra vc pegar esse auth, basta usar o seguinte codigo.

firebase.auth().currentUser.getToken().then(data => {

let auth = data;

fetch('https://rjr-backend.firebaseio.com/clientes/.json?shallow=true&auth=' + auth).then(resp => { return resp.json(); }).then(data => { this.gridOptions.totalItems = Object.keys(data).length; console.log(Object.keys(data).length) });

});

É isso, ai o resto é só implementar!!!

15/04/2018 Database / sql server

select top ${take} * from (

SELECT

      isnull(Ltrim(RTRIM([CPFCGC_PES])),'') as documento

      ,isnull(RTRIM([IE_PES]), '') as inscricaoEstadual

      ,isnull(Ltrim(RTRIM([NOME_PES])), '') as nome

      ,ROW_NUMBER() OVER (order by CPFCGC_PES) AS rowid

      ,isnull(RTRIM([EMAIL]),'') as email, isnull((select enderecos.* from (SELECT RTRIM(PE.BAIRRO_ENDE) as bairro, 

                     RTRIM(PE.RUA_ENDE) as logradouro,

RTRIM(PE.CEP_ENDE) as cep,

RTRIM(CIDADES.CIDADES) as cidade,

RTRIM(CIDADES.UF) as estado,

RTRIM(TIPOS_ENDERECOS.NOME_TIPE) tipoEndereco 

              FROM   [cobsystems].[dbo].[PESSOAS_ENDERECOS] PE inner join [cobsystems].[dbo].[CIDADES] on PE.CIDADE_COD = CIDADES.CODIGO  inner join [cobsystems].[dbo].[TIPOS_ENDERECOS] on TIPOS_ENDERECOS.COD_TIPE = PE.COD_TIPE

              WHERE  PE.COD_PES = p.COD_PES) as enderecos FOR json path, INCLUDE_NULL_VALUES), '') AS enderecos, isnull((select telefones.* from ( 

              SELECT  RTRIM(PT.NR_TEL) as numero, RTRIM(TIPOS_TELEFONES.NOM_TIP) as tipo

              FROM   [cobsystems].[dbo].[PESSOAS_TELEFONES] PT inner join [cobsystems].[dbo].[TIPOS_TELEFONES] on pt.TIPO_TEL = TIPOS_TELEFONES.COD_TIP

              WHERE  PT.COD_PES = p.COD_PES) as telefones FOR json path, INCLUDE_NULL_VALUES), '') AS telefones FROM [cobsystems].[dbo].[PESSOAS] as p where CPFCGC_PES <> '') as c where rowid > ${skip} order by rowid

funciona da seguinte maneira, o take é a quantidade de registros

o skip, é a posição...ou seja, skip = 0, inicia na posicao 0, skip 50, inicia na posicao 50 e assim por diante.

15/04/2018 Development / java script

Firebase ou você AMA ou você ODEIA!

O firebase não tem uma resposta muito boa, tipo um formato de que um tratamento decente.

No caso de paginacao de dados, é ainda pior.

Pra voê saber quantos registros você tem na sua base, tem um macete.

https://SEUPROJETO.firebaseio.com/SUAREFERENCIA/.json?shallow=true

Esse json?shallow=true, retorna somente as KEYS que estao no banco.

Na minha opiniao é uma GAMBIARRA, mas ajuda, quando se trata de ter um banco com 1milhao de registros.

13/04/2018 Development / angular

Quem trabalha com firebase, deve "OBRIGATORIAMENTE" seguir oque os caras falam:

Melhorar a eficiência dos listeners

Coloque os listeners na última parte possível do caminho para limitar a quantidade de dados que eles sincronizam. Seus listeners devem estar perto dos dados que você quer detectar. Não coloque listeners na raiz do banco de dados, pois isso resulta em downloads de todo o seu banco de dados.

Adicione consultas para limitar os dados retornados pelas suas operações de detecção e use listeners que fazem o download somente de atualizações de dados. Por exemplo, on() em vez de once(). Use .once() somente em ações que realmente não exigem atualizações de dados. Além disso, classifique suas consultas com orderByKey() sempre que possível para alcançar o melhor desempenho. A classificação com orderByChild() pode ser de seis a oito vezes mais lenta. A classificação com orderByValue(), por sua vez, pode ser muito lenta para grandes conjuntos de dados porque requer uma leitura de todo o local, desde a camada de persistência.

Lembre-se também de adicionar listeners de maneira dinâmica e de removê-los quando não forem mais necessários.

#ficadica

11/04/2018 Database / sql server

Esse é o maior pulo do gato que eu descobri ultimamente em relação a conversão de Select para Json.

Essa primeira query, cria um objeto P e um objeto F, nao deixando tudo na mesma linha

SELECT 

      [SENHA_USU] as password

      ,[NIVEL_USU] as nivel

      ,[ATIVO_USU] as ativo

      ,[NOME_PES] as displayName

  ,EMAIL as email

      ,[DT_ENTRADA_FUNC] as dtEntrada

      ,[DT_SAIDA_FUNC] as dtSaida

      ,[SALARIO_FUNC] as salario

      ,[CARGO_FUNC] as cargo

      ,[COMMISSAO_FUNC] as comissao

  FROM [cobsystems].[dbo].[USUARIOS] inner join FUNCIONARIOS_OLD on USUARIOS.COD_FUNC = FUNCIONARIOS_OLD.COD_FUNC inner join PESSOAS on PESSOAS.COD_PES = FUNCIONARIOS_OLD.COD_PES order by COD_USU  FOR json auto

 

query arrumada

Essa query deixa tudo na mesma linha!

SELECT m.* 

         FROM (

 

SELECT 

      U.SENHA_USU as password,

      U.NIVEL_USU as nivel,

  IIF(U.ATIVO_USU = 1, 'true', 'false') as ativo,

 

      P.NOME_PES as displayName,

  isnull(P.EMAIL, '') as email,

      F.DT_ENTRADA_FUNC as dtEntrada,

      F.DT_SAIDA_FUNC as dtSaida,

      convert(int, isnull(F.SALARIO_FUNC, 0)) as salario,

      F.CARGO_FUNC as cargo,

      convert(int, isnull(F.COMMISSAO_FUNC,0)) as comissao

  FROM [cobsystems].[dbo].[USUARIOS] as U inner join [cobsystems].[dbo].[FUNCIONARIOS_OLD] F on U.COD_FUNC = F.COD_FUNC inner join [cobsystems].[dbo].[PESSOAS] P on P.COD_PES = F.COD_PES

 

) AS m

         FOR JSON AUTO

15/03/2018 Development / java script

Essa foi a forma menos feia que eu encontrei pra não ter que ficar setando toda hora o createdAt, createdBy, updatedAt, updatedBy... É um baaaaaaaita jump the cat, hehehe!! Espero que sirva pra alguem tambem!

var set = firebase.database.Reference.prototype.set;
firebase.database.Reference.prototype.set = function(value, onComplete){
  value['createdAt'] = firebase.database.ServerValue.TIMESTAMP;
  value['createdBy'] = firebase.auth().currentUser.displayName;
  return set.apply(this, arguments);
}
var update = firebase.database.Reference.prototype.update;
firebase.database.Reference.prototype.update = function(value, onComplete){
  value['updatedAt'] = firebase.database.ServerValue.TIMESTAMP;
  value['updatedBy'] = firebase.auth().currentUser.displayName;
  return update.apply(this, arguments);
}

 

13/03/2018 Development / angular

Oque é um decorator?

Basicamente ele é utilizado para sobreescrever métodos antes que de fato o método original seja chamado!

Vamos imaginar o seguinte cenario:

Temos alguns endpoints que realizam Create e Update no banco. E para cada um desses métodos, eu quero salvar o dia da criacao do registro e quem fez o cadastro, e o dia da alteracao do registro e que fez o cadastro!

Usando MongoDB é muito facil fazer isso, basta a gente indicar no model um timestamp: true

Exemplo:

var clienteSchema = new mongoose.Schema({

nome: {type: String}

},{

    timestamps: true

});

Qualquer inclusão ou alteração que ocorrer, o mongo já incluirá os valores da data da criação e ou alteração!

Mas no nosso caso, não estamos usando MONGO e tambem queremos incluir a pessoa que fez a ação!

Voltando ao nosso cenário, criamos o nosso Service que receberá os dados e enviará para API.

Eu vou fazer bem básico, porque a intenção aqui é focar no decorator!!!

Service.create = (data)=> {

    data.createdAt = firebase.database.ServerValue.TIMESTAMP; // ou new Date().getTime()

    data.createdBy = firebase.auth().currentUser.displayName; // ou currentUser.uid;

  return this._$firebaseArray(firebase.database.ref('suaRefencia')).$add(data)  

}

 

Service.update = (id, data)=> {

    data.createdAt = firebase.database.ServerValue.TIMESTAMP; // ou new Date().getTime()

    data.createdBy = firebase.auth().currentUser.displayName; // ou currentUser.uid;

  return this._$firebaseObject(firebase.database.ref('suaRefencia').child(id)).$save(data)  

}

Olha que chato, se toda vez que a gente criar um servico, ter que ficar colocando esse código, createdAt, createdBy, updatedAt, updatedBy

O ideial é quando a gente chamar o $add ou $save, antes de executar o método, ele inclua essas propriedades no nsso objeto data.

É ai que entra o decorator!!!

let app = angular.module('app', []);

app.config(function($provide) {

    $provide.decorator('$firebaseArray', function($delegate, $window) {

        var _add = $delegate.prototype.$add;

        $delegate.prototype.$add = function (newData) {

            newData['createdAt'] = $window.firebase.database.ServerValue.TIMESTAMP;

            newData['createdBy'] = $window.firebase.auth().currentUser.displayName; //uid

 

            return _add.call(this, newData);

        };

        return $delegate;

    });

})

app.config(function($provide) {

    $provide.decorator('$firebaseObject', function($delegate, $window) {

        var _save = $delegate.prototype.$save;

        $delegate.prototype.$save = function () {

            this['updatedAt'] = $window.firebase.database.ServerValue.TIMESTAMP;

            this['updatedBy'] = $window.firebase.auth().currentUser.displayName;

            return _save.call(this);

        };

        return $delegate;

    });

})

Agora no nosso controller, a gente faz a chamada do Service

let data = {

  nome: 'Joao da Silva';

  idade: 33

}

Service.create(data);

Nosso service chamado o firebaseArray, mas antes entra no decorator, que insere a data da criacao e o nome do usuário logado no firebase!

E assim, a gente finaliza nossa tarefa.

Espero que ajude!

 

 

 

 

 

 

 

 

06/03/2018 Corridas / Maratonas

32km em Ubatuba-SP

Essa prova foi realizada dia 04/03/2018 e meu tempo total foi de: 06:55:15

20/02/2018 Development / java script

Trabalhar com firebase é muuuuuuuuuuuuuuito produtivo! Super rapido fazer as paradas, subir aplicação, mas tem 2 coisas que eu vi que são chatinhas, uma eu já citei aqui que é o lance de não ter um JOIN decente no database, a outra, porém é necessário, é que a gente só consegue manipular os dados de usuários através do servidor. No client, não é possível fazer um firebase.auth().getUser(uid) por exemplo, e tem total sentido isso né!

Então, acaba que a gente tem que meter a mão na massa e fazer as Cloud Functions, que são tipos umas funções que você vai poder executar do lado do servidor. Nesse caso, eu precisei meeeeeesmo, fazer um CRUD pra manipular os dados de usuários. Então eu vou compartilhar com vocês. É só trocar a chave da public key, fazer o deploy e correr pro abraco!

const express = require('express');

const app = express();

const functions = require('firebase-functions');

const admin = require("firebase-admin");

const bodyParser = require('body-parser');

const cors = require('cors');

 

app.use(cors({ origin: true }));

app.use(bodyParser.urlencoded({ extended: true }));

app.use(bodyParser.json());

 

admin.initializeApp({

  credential: admin.credential.cert({

    projectId: "AQUIVEMSEUPROJETO",

    clientEmail: "AQUIVEMOSEUEMAILPROVADO",

    privateKey: "-----BEGIN PRIVATE KEY-----AQUIVEMASUACHAVEPRIVADA==\n-----END PRIVATE KEY-----\n"

  }),

  databaseURL: "https://AQUIVEMOSEUPROJETO.firebaseio.com"

});

 

//GET

app.get('/:id', (req, res) => {

let uid = req.params.id;

admin.auth().getUser(uid)

  .then(function(userRecord) {

    resp.json(userRecord.toJSON());

  })

  .catch(function(error) {

    res.json(error);

  });

});

 

//POST

app.post('/', (req, res) => {

let data = req.body;

console.log(data);

 

admin.auth().createUser(data)

  .then(function(userRecord) {

    res.json(userRecord);

  })

  .catch(function(error) {

    res.json(error);

  });

});

 

//DELETE

app.delete('/:id', (req, res) => {

let uid = req.params.id;

admin.auth().deleteUser(uid)

  .then(function(userRecord) {

    res.json(userRecord.toJSON());

  })

  .catch(function(error) {

    res.json(error);

  });

});

 

//UPDATE

app.put('/:id', (req, res) => {

let uid = req.params.id;

let data = req.body;

admin.auth().updateUser(uid, data)

  .then(function(userRecord) {

    res.json(userRecord.toJSON());

  })

  .catch(function(error) {

    res.json(error);

  });

});

exports.api = functions.https.onRequest(app);

Espero que sirva!

20/02/2018 Development / macetes

Agora no bootstrap 4 existe uma série de classes utilitarias, aquelas classes que são uma mão na roda. Uma delas é pra margin e padding e funciona da seguinte maneira.

m = margin
p = padding

e as combinações são

m-0, m-1, m-2, m3, m-4, m-5, sendo que m-0, tira completamente a margin e as outras você vai adicionado 15% da aréa da margin.

E tem tambem a possibilidade de setar a posição da margin. Ex: mt-0 isso é o margin-top. Entao temos: mt, mb, ml, mr

E por fim se quisermos deixar centralizado a margin, usamos o mx-auto!

A mesma coisa serve para o padding ;-)

Espero que ajude!