Tutorial app Android com Firebase – Realtime Database

Este artigo é uma continuação da série “Tutorial app Android com Firebase” onde ensino como utilizar todos os serviços oferecidos pela plataforma de Backend-as-a-service do Google. Hoje, vou falar do serviço mais famoso deles: o realtime database, que permitiu a muitos desenvolvedores de apps que não sabem criar APIs para fazer conexão com banco de dados externo, pudessem colocar seus apps em produção rapidamente.

Não apenas isso, como o próprio nome sugere, a realtime database do Firebase permite comunicação em tempo real com o banco de dados, incluindo uma arquitetura no melhor estilo dos padrões Observer e Pub-Sub. Além disso, permite salvamento offline com sincronização automática quando a conexão é reestabelecida.

Usarei como exemplo neste tutorial o app ForcaVendas que iniciamos no primeiro artigo desta série. No entanto, não se preocupe, ele apenas possui uma tela de login e uma MainActivity com um olá mundo. Sendo assim, você consegue fazer este tutorial sem ter feito os anteriores, desde que já saiba como programar para Android, é claro. Também existe a possibilidade de baixar os fontes do app através do formulário existente no final de cada post desta série.

#1 – Configurando o Realtime Database

Primeiramente, para configurar o database do Firebase para o seu app, vá no menu Tools > Firebase do Android Studio e clique na opção “Save and retrieve data” da seção Realtime Database.

Configurando o Firebase
Configurando o Firebase

Na seção seguinte que vai se abrir temos os passos de configuração propriamente ditos. O passo 1 é bem simples e exige que você se conecte ao Firebase primeiro.

Realtime Database
Realtime Database

O segundo passo adiciona as dependências para se trabalhar com Realtime Database no seu app e pedirá confirmação para instalar dependências e alterar alguns arquivos de configuração.

Feito isso, estamos prontos para usar nosso banco realtime!

#2 – Entendendo o Realtime Database

Como explicado no site oficial do Firebase Realtime Database:

O Firebase Realtime Database é um banco de dados hospedado na nuvem. Os dados são armazenados como JSON e sincronizados em tempo real com todos os clientes conectados.

Ou seja, você cria o seu banco na nuvem do Firebase e conecta seu app nele para enviar e receber objetos JSON em tempo real. Simples assim. As mudanças no banco são refletidas automaticamente para todos os dispositivos (e aplicações, pois você pode usar na web também) conectados, em tempo real (daí o nome). Isso lembra os documentos do MongoDB. O site oficial ainda diz que:

Todos os dados do Firebase Realtime Database são armazenados como objetos JSON. Pense no banco de dados como uma árvore JSON hospedada na nuvem. Ao contrário de um banco de dados SQL, não há tabelas nem registros. Quando você adiciona dados à árvore JSON, eles se tornam um node na estrutura JSON com uma chave associada.

Um recurso muito importante do Realtime Database é que combinando com o suporte de autenticação do Firebase você pode definir quem tem acesso a quais dados, garantindo a autorização dos mesmos. Existe uma opção de deixar o seu banco público, mas na maioria dos casos isso não é recomendado.

Como o Realtime Database é associado ao seu projeto Firebase, por padrão ele só permite o acesso aos dados por usuários autenticados, como mostra a imagem abaixo do Firebase Console.

Firebase Realtime Database Authentication
Firebase Realtime Database Authentication

Caso não tenha feito o tutorial de autenticação em Firebase, você pode opcionalmente deixar os dados públicos na mesma tela acima. De qualquer forma recomendo dar uma olhada no respectivo tutorial para entender o básico da plataforma Firebase, pois é lá onde explico isso.

Outro recurso interessantíssimo do Realtime Database é o suporte offline. Se seu app ficar sem Internet, os dados serão salvos localmente e depois sincronizados quando a conexão voltar.

Assim como no MongoDB, a modelagem de um banco no Realtime Database deve ser feita com cuidado, sempre tendo em mente como desejará consultar estes dados depois. Algumas dicas incluem:

  • não aninhe muitos níveis dentro dos seus objetos JSON. Apesar do Firebase suportar até 32 níveis, isso não é uma boa prática por tornar consultas muito pesadas e escritas muito arriscadas.
  • evite a normalização excessiva (espalhando demais os dados) e foque na consulta rápida, mesmo que isso exija duplicação de dados. Em bancos NoSQL, tamanho não é problema, desde que o dado esteja fácil de ler e baixar.

Vale salientar que dificilmente você terá custos enquanto estiver estudando como usar o Realtime Database, mas que dificilmente não terá considerando que para seu app ir para produção você irá querer recursos mais avançados como backup do seu banco, por exemplo, disponível apenas nos planos superiores.

#3 – Criando a tela de Cadastro

Mesmo que não tenha feito os outros tutoriais de Firebase aqui do blog, não tem problema. Você apenas precisar ter uma aplicação com o template padrão do Android Studio, aquele com a MainActivity contendo um “Hello World” e um floating button no canto inferior direito.

Nos tutoriais anteriores comentei que iria fazer um app de Força de Vendas para autônomos. A ideia é apenas registrar os pedidos, compras e dívidas, de uma maneira fácil de buscar depois, ajudando na organização do vendedor, que geralmente usa caderninhos para isso. Assim, essa MainActivity (a tela inicial) futuramente será a listagem de registros principal do app. Como não temos dados para serem listados ainda, vamos apenas programar o floating button dessa tela nos levar para uma tela de cadastro.

Essa alteração é bem simples, troque o ícone do floating button para algo que faça mais sentido do que o envelope tradicional usando o XML abaixo no activity_main.xml (dentro da pasta res/layout):

Note que alterei somente a propriedade srcCompat que determina o ícone, onde estou usando o ícone de sistema do botão de “+”, que representa bem uma adição.

Agora vamos criar a próxima Activity, de cadastro, do tipo Empty Activity com o nome de AddActivity, aproveitando que o Android Studio criará para nós o arquivo de layout activity_add.xml automaticamente. Mas o que irá ter nesta tela?

Pensando em um fluxo de uso bem simples, os registros deverão conter uma descrição, um valor, uma data e um tipo. O tipo pode ser Venda Paga, Venda Não Paga (fiado, bem comum entre vendedores autônomos) e Venda Futura (apenas tirou um pedido). Obviamente esta é apenas uma proposta, você pode criar algo mais elaborado se quiser.

Com isso em mente, edite seu activity_add.xml para que pareça com isso:

Tela de Cadastro
Tela de Cadastro

Caso você não faça ideia de como criar este layout, recomendo fazer o tutorial de Constraint Layout primeiro ou verificar as diversas lições presentes em meu livro. Se estiver na correria, apenas copie e cole o código XML abaixo no seu activity_add.xml:

Note que para o Spinner exibir corretamente os tipos eu tive de criar outro arquivo XML, desta um de valores (tipos.xml), na pasta res/values. Neste arquivo XML de strings, o qual eu reproduzo abaixo, apenas listo os textos dos valores possíveis, considerando aqui que eles são fixos (caso contrário eu deveria carregar do banco).

E para referenciar este XML no Spinner (o componente visual de seleção de tipo) você usa a propriedade entries, como abaixo (esse código já está contemplado no XML completo da página que mostrei antes):

Agora para conseguirmos chegar até esta página e ver se a tela ficou ok no simulador ou no seu device android físico, devemos programar a ação do floating button existente na MainActivity. Essa ação já vem programada no evento onCreate da Actvity por padrão, para apenas exibir uma mensagem, vamos trocar para realizar a troca de tela.

Com isso programado, já temos o suficiente para testar a nossa aplicação no simulador e ver se conseguimos chegar até a tela de cadastro. Se você veio fazendo este tutorial deste o início, terá de se autenticar como um usuário válido primeiro.

Após você testar e se certificar que este básico está funcionando, vamos fazer mais um ajuste pequeno, porém útil para facilitar a digitação.

Data Atual

O campo data deve vir com a data atual por padrão. Para fazer isso, no onCreate da AddActivity, adicione o seguinte código que pega a data atual e a coloca no campo com id txtData (eu defini esse id para o campo de data, talvez o seu seja diferente):

Quando você abrir a tela de cadastro, encontrará a data atual no respectivo campo. É uma coisa pequena, mas ajuda.

Como este post está ficando extenso, deixarei a parte de conexão com o banco para leitura e escrita para o próximo artigo que deve sair em breve. Aguarde!

* OBS: curtiu o post? Então dá uma olhada no meu livro de Android clicando no banner abaixo pra aprender outras dicas incríveis!

Criando apps para empresas com Android

Tutorial MongoDB para iniciantes em NoSQL – Parte 5

MongoDB Logo
MongoDB Logo

Atualizado em 09/12/17!

E chegamos ao quinto artigo da minha série de tutoriais de MongoDB para iniciantes em NoSQL. Caso esteja caindo de pára-quedas nesta série, seguem os links dos posts e seus respectivos assuntos:

Neste quinto artigo tratarei de como manipular documentos que possuam subdocumentos e campos multivalorados, usando como base o banco de blog que modelamos no artigo anterior.

Boa parte do conteúdo deste artigo se encontra na segunda metade do vídeo abaixo que gravei pra Umbler. Além da leitura, recomendo a visualização para ver como tudo fica na prática:

CRUD com Subdocumentos

No segundo artigo desta série nós vimos como buscar, inserir, atualizar e excluir documentos em coleções MongoDB. No entanto, sempre com documentos planos, sem níveis, a forma mais básica de armazenar dados.

Mas e quando temos um subdocumento dentro de outro documento, assim como o autor dentro de um artigo de blog?

Vamos começar pelo C do CRUD, que no caso do MongoDB é representado pelo método insert. O comando abaixo insere um novo artigo incluindo o subdocumento ‘autor’:

Note que eu não passo o _id do artigo pois ele é autoincremental e controlado pelo próprio MongoDB. Já no caso do autor, ele pertence à outra coleção, a de autores, e o _id que está junto dele deve ser o mesmo do autor original na sua referida coleção. Imagina-se que em uma aplicação que salve um artigo, que a informação do autor do artigo esteja em sessão ou em um componente de tela para ser passada ao MongoDB corretamente.

Falando do R do CRUD, o find no MongoDB, podemos facilmente usar campos de subdocumentos como filtros em nossas consultas, como segue:

Essa consulta retorna todos os artigos cujo nome do autor seja literalmente Luiz. Qualquer filtro existente pode ser usado aqui, sobre qualquer campo do subdocumento autor, mas atenção à forma que referenciei o campo, usando o nome do subdocumento, seguido de um ‘.’, e depois o nome do campo. Repare também que neste caso o uso de aspas ao redor da expressão é obrigatório.

Seguindo com o U do CRUD, vale tudo o que vimos até agora. Para substituir documentos que possuam subdocumentos usando o comando update, você tem de passar eles também, para não se perderem na atualização, como abaixo:

Se for usar um campo de um subdocumento no filtro do update, valem as mesmas regras do filtro do find que expliquei anteriormente. O mesmo vale caso queira aplicar algum update operator em um campo de um subdocumento. Quer um exemplo prático?

Na modelagem de blog que fizemos no post anterior, replicamos o nome e _id do autor em todos os posts escritos por ele. Mas o que acontece caso o nome do autor seja alterado no documento original dele, que fica na coleção de autores?

Teremos de replicar esta alteração em todos os artigos que tenham sido escritos por aquele autor, como abaixo. Neste exemplo, suponha que o autor Luiz teve o nome alterado para Luiz Fernando, então temos de atualizar todos os posts escritos por ele. Como é somente esta pequena informação que mudou, usaremos o update-operator $set, para não ter de sobrescrever os documentos inteiros.

Para um update mais preciso, eu poderia substituir o filtro autor.nome por autor._id, considerando que nomes de autores podem ser repetir em um mesmo blog.

Com os update-operators $set, $unset e $rename é possível manipular os campos dos subdocumentos também, da mesma forma que faria com o documento principal, apenas usando a notação “subdocumento.campo”.

Finalizando o CRUD com subdocumentos, o D de delete é realizado usando as mesmas regras de filtro do find, caso queira excluir todos os documentos que possuam um valor específico em um campo de um subdocumento. Sem mistério algum.


CRUD com campos multivalorados

Outra preocupação é com a manipulação de elementos em campos multi-valorados, algo inexistente em bancos relacionais que sempre assumem relações 1-N ou N-N nestes casos. Salvo gambiarras que já vi por aí de salvar strings CSV ou JSON em coluna de registro e outras loucuras que sempre acabam gerando dor de cabeça pois não são pesquisáveis.

Começando pelo C do CRUD, o insert do MongoDB funciona de maneira muito óbvia para campos multivalorados: apenas passe null para nenhum valor ou o array (entre colchetes) de valores iniciais daquele elemento (sim, o MongoDB permite que depois você adicione ou remova elementos).

Se você procurar no exemplo anterior de insert, verá que passei null no campo multivalorado de tags do artigo. A outra opção, passando valores iniciais, segue abaixo:

Neste caso o campo multivalorado tags é um array de strings. Caso deseje, você pode inserir um documento que possua campos multivalorados de documentos também, como no caso das categorias que modelamos no post anterior:

Mas é quando entramos no R do CRUD com campos multivalorados em MongoDB que começamos a explorar um novo universo de possibilidades e novos filter-operators da função find.

Considere que temos três artigos salvos na nossa base MongoDB (omitirei os campos que não nos importam no momento):

Para fazer buscas usando campos multivalorados como filtro é muito simples: você deve usar os operadores de filtro $all e $in. Exemplo de consulta por todos os artigos que possuam todas (ALL) as seguintes tags NodeJs e MongoDB :

O operador $all vai garantir que só sejam retornados artigos que possuam no mínimo as duas tags informadas (somente o Artigo 1), equivalente à consulta SQL abaixo:

Agora um exemplo de consulta por todos os artigos que possuam uma (IN) das seguintes tags NodeJs ou MongoDB:

Neste caso todos os três artigos serão retornados, assim como no equivalente SQL abaixo (coloquei reticências por preguiça de preencher todas as colunas):

Mas agora se quisermos apenas os artigos que possuam ao menos uma categoria (o campo de categorias é multivalorado, lembra?) com o nome Desenvolvimento?

Quando aplicamos um filtro sobre um campo que é multivalorado o MongoDB entende que podemos passar um novo filtro a seguir, que será aplicado aos campos do subdocumento. Por exemplo:

Vai retornar todos os documentos que tenham ao menos uma categoria cujo nome seja ‘Desenvolvimento’. Também poderia usar filter-operators se fosse necessário como $gte, $regex, etc.

Avançando para o U do CRUD, no update de campos multivalorados também temos diversas opções a serem exploradas pois é no update que adicionamos e removemos elementos do nosso array, quando quisermos fazê-lo. Para tais tarefas deve-se usar os operadores $pull (remove o elemento do array) e $push (insere o elemento no array), sempre dentro de um comando de update, como segundo parâmetro (update-operator). Ex:

Pode parecer um pouco estranho no início, mas na verdade é muito mais simples, pois é a mesma ideia que já fazemos há anos com coleções em linguagens de programação, onde geralmente temos métodos como add e remove ou assemelhados.

Finalizando, o D do CRUD, em campos multivalorados funciona da mesma forma que o find, considerando que no deleteOne e deleteMany do MongoDB também passamos um filtro por parâmetro.

Quer aprender outras dicas? Leia o que escrevi sobre boas práticas com MongoDB no blog da Umbler!

Curtiu o post? Que tal aprender a usar MongoDB com Node.js? Então clica no banner abaixo e dá uma conferida no meu livro sobre programação web com Node.js!

Lançamento do meu livro de MongoDB


Foi em 2015 que conheci MongoDB. Sim, eu estava bem atrasado considerando que a tecnologia havia sido lançada em 2009 e desde 2010 já existiam grandes projetos usando-a. Como sempre gostei de criar aplicações com massas grandes de dados, como meus mecanismos de busca, logo me interessei pelo approach baseado em documentos do Mongo e facilidade de consultar. E pela performance, é claro.

Assim como fiz em 2012, conforme ia iniciando meus estudos de Android, fui documentando tudo o que aprendia e testava sobre MongoDB, ao mesmo tempo que estudava e aplicava outra tecnologia em meus projetos: Node.js.

Obviamente não comecei meus estudos partindo do zero, uma vez que já trabalho com sistemas que usam bancos de dados há cerca de 10 anos. Todo o meu conhecimento de banco de dados (que engloba muito SQL Server e um pouco de outros bancos), aliado às boas práticas de Engenharia de Software, Gestão de Projetos, Testes de Software, etc formaram o profissional que sou hoje.

No uso de MongoDB eu tenho experiência de mais de dois anos na data que escrevo este post e uma meia dúzia de projetos entregues e funcionando.

Pois então que há alguns meses decidi escrever um novo livro. O segundo de 2017 (o primeiro foi sobre Node.js), justamente sobre todo esse conhecimento de MongoDB que possuo que já me renderam algumas ofertas de emprego bem interessantes e alguns milhares de reais em projetos entregues usando este banco de dados.

Esse livro chama-se MongoDB para Iniciantes, e está à venda desde essa semana na Amazon.

Apesar do seu tamanho, 120 páginas, é um livro bem completo. Ele não se limita a listar e explicar comandos para consultar e manipular o MongoDB. Ele parte do princípio que você quer entender como funciona a orientação à documentos, que quer saber como se gerencia minimamente um servidor Mongo. Com uma didática clara e objetiva, como todos livros de minha autoria (quem já leu os demais sabe do que estou falando), e que pega o leitor pela mão e ensina desde os conceitos mais básicos até tudo que é necessário para ter um banco modelado corretamente e rodando, pronto para suas aplicações se conectarem. Inclusive ensina como usar MongoDB com Node.js, ASP.NET Core e PHP, sem entrar em muitos detalhes destas linguagens.

Do primeiro insert até comandos mais elaborados para manipulação de campos multi-valorados, índices, relatórios de performance e subdocumentos, MongoDB para Iniciantes é para quem está começando a trabalhar com MongoDB e bancos relacionais e está completamente confuso com a quantidade de tutoriais, informações conflitantes e artigos fora de ordem. Nele, ensino a usar tudo o que deu certo em meus projetos com MongoDB nos últimos anos, um banco não-relacional que é bom, confiável e que possui grande mercado.

Neste livro você vai aprender:

  • introdução aos bancos não-relacionais e NOSQL;
  • execução do servidor MongoDB;
  • conexão usando o client nativo Mongo;
  • quando usar e quando não usar MongoDB;
  • comandos básicos e intermediários para consultas;
  • comandos básicos e intermediários para inserção, atualização e exclusão de documentos;
  • como extrair relatório de performance de suas queries;
  • criação de índices;
  • gerenciamento mínimo de servidor (backup, restore, import);
  • como modelar os seus documentos usando o paradigma do MongoDB;
  • como criar aplicações reais usando Node.js, PHP e ASP.NET Core;
  • dezenas de boas práticas com MongoDB;

Novamente, devido às atualizações constantes, optei apenas por ter somente versão digital, que você pode ler no Kindle, no PC usando o ler.amazon.com e no smartphone/tablet usando o app Kindle Cloud Reader. Livros de tecnologia impressos tendem a ficar obsoletos rapidamente, coisa que eu detesto.

Além disso, caso assine o Kindle Unlimited (primeiro mês grátis e depois R$20/mês), você pode ler o meu livro e milhares de outros títulos gratuitamente.

Se ainda não é cliente da Amazon, esta é uma excelente oportunidade de começar com o pé direito. Modéstia à parte. 😉

Leia a amostra grátis do livro abaixo e tire suas próprias conclusões: