Firebase Database para Desenvolvedores SQL — O Básico

Rosário Pereira Fernandes
GDG Maputo

--

ATENÇÃO! O FIREBASE TEM AGORA O CLOUD FIRESTORE QUE É UM SERVIÇO DE BASE DE DADOS MAIS SIMPLES DE ESTRUTURAR. SE VOCÊ ESTIVER A COMEÇAR UM PROJECTO, RECOMENDO QUE UTILIZE O FIRESTORE AO INVÉS DA REALTIME DATABASE.

Quando conheci o Firebase, a primeira surpresa que tive foi a forma como funciona a Firebase Realtime Database: é uma árvore JSON (NoSQL).

E tenho a certeza que foi também uma surpresa para maior parte dos desenvolvedores quando falei-lhes sobre o Firebase no GDG Maputo DevFest 2016. A primeira pergunta que surgiu foi:

“Como converter as minhas tabelas SQL para utilizar no Firebase?”

E foi por isso que decidi escrever esta série de artigos onde procuro ajudar Desenvolvedores SQL a adaptarem-se à lógica da Firebase Realtime Database. Nesta série, vou mostrar código java equivalente à certas queries SQL. Se você programa em outras linguagens como javascript ou Objective-C, não se preocupe, porque a estrutura do código não se altera; a única diferença está na sintaxe.

Se você ainda não conhece o Firebase, por favor, leia este artigo do Dario Mungoi, pois o meu artigo não fará nenhum sentido para quem nunca usou o Firebase.
Para quem já conhece o Firebase, mas não tem nenhuma experiência com a Realtime Database, pode ver o artigo Realtime Databases — part 1 para entender como funciona este serviço.

O básico de todas as bases de dados

Em todos os sistemas de gestão de base de dados, temos sempre 4 funções básicas: inserir, ler, actualizar e remover dados.

Vamos então fazer uma comparação de como executamos essas funções em SQL e como devemos fazer isso no firebase. Para isso, vamos utilizar como exemplo uma base de dados para uma aplicação onde os utilizadores podem juntar-se à grupos de estudo criados na aplicação.

SQL:

Em SQL teriamos as seguintes tabelas:

E para conhecermos os participantes de cada grupo:

Firebase:

Convertendo as tabelas SQL para uma árvore JSON, teriamos o seguinte:

Vamos ver então como gerir estes dados.

1 — Inserir

Vamos inserir um usuário com o id 2 na tabela de usuários.

Em SQL:

Em SQL utilizamos a query:

INSERT INTO usuario (id, nome, email, idade, cidade) VALUES (‘2’, ‘Joana’, ‘joana@email.com’, ‘21’, ‘beira’);

No Firebase para Android:

Em Java, para adicionarmos um novo utilizador, temos de criar primeiro a classe Utilizador para facilitar a escrita e leitura de utilizadores. Abaixo vai a estrutura da classe:

Atenção: ao criar uma classe que será adicionada à Realtime Database, as variáveis devem ser públicas ou possuir getters e setters públicos. E é obrigatório que exista um constructor vazio.

Vamos então adicionar o novo utilizador à base de dados:

Utilizador user = new Utilizador(2, "Joana", "joana@email.com", 21, "beira"); //instancia do novo utilizador
DatabaseReference raiz = FirebaseDatabase.getInstance().getReference(); //Esta variavel indica a raiz da nossa árvore JSON
raiz.child("usuarios/2").setValue(user);//Colocar o usuario com o id 2

Com o código acima, vamos ao nó “usuários” e dentro dele criamos um nó “2”, que conterá os dados do usuário instanciado:

Você deve estar a pensar: E nas tabelas onde tenho o id como AUTO_INCREMENT, como faço?
Bom, na Realtime Database, não é boa ideia utilizar números em sequência como chave primária, exactamente por ela funcionar em tempo real. Podemos ter vários utilizadores a escreverem ao mesmo tempo e isso pode fazer com que obtenham o mesmo id.

Para resolver este problema, a database é capaz de criar ids aleatórios para cada utilizador. Para isso, basta utilizarmos o código:

raiz.child("usuarios").push().setValue(user);

E desta vez, teremos algo como:

Você deve estar preocupado em saber como iremos encontrar este usuário com um id tão difícil de se ler. Mas isto é algo que veremos nos próximos artigos.

2 — Actualizar

Vamos supor que por engano colocamos o usuário “Maria”, enquanto devia ser “Mario”. Como fazemos para actualizar os dados?

Em SQL:

UPDATE TABLE usuarios SET nome = 'Mario' WHERE id_usuario = 8;

No Firebase para Android:

Podemos utilizar a mesma instância do usuário, alterando apenas o nome:

user.nome = "Mario";
raiz.child("usuarios/8").setValue(user);

Atenção: Se a instancia user não tiver alguns dados, como email ou idade por exemplo, esses dados serão eliminados na database e o nó irá conter apenas o atributo nome. Tome bastante cuidado ao editar dados. Vários desenvolvedores, tanto iniciantes como experientes, muitas vezes perdem dados por acções deste tipo.

3 — Remover

Em SQL:

Para removermos o usuário de ID 8, basta executar a query:

DELETE FROM usuarios WHERE id_usuario = 8;

No Firebase para Android:

raiz.child("usuario/8").setValue(null);

Atenção: Assim como na alteração de dados, remover dados também pode ser muito perigoso. Tenha atenção ao colocar um nó como nulo, pois isso irá remover todos os outros nós que estejam dentro deste nó.

4 — Ler

Vamos ler os dados do usuário de id 1.

Em SQL:

SELECT * FROM usuarios WHERE id_usuario = 1;

No Firebase para Android:

A leitura de dados na realtime database não é tão “directa” como no SQL. Para ler dados aqui, temos de recorrer à listeners. E existem 2 tipos de listeners: para ler apenas uma vez e outro para ler e manter os dados actualizados em tempo real. (mais detalhes sobre este assunto, neste artigo)

Vamos ver o listener que mantém os dados actualizados:

raiz.child("usuarios/8").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot)
{
Utilizador user = dataSnapshot.getValue(Utilizador.class);
}
@Override
public void onCancelled(DatabaseError databaseError) {
//Se ocorrer um erro}
});

Eu deixei a parte de leitura por último por ser a operação mais complexa quando se trata de base de dados. Você poderá querer fazer leituras diferentes, como: “Todos os usuários”, “Todos os usuários que participam no grupo x”, “Todos os usuários menores de idade”, etc.

Por isso, no próximo artigo, mostro algumas técnicas avançadas para leitura de dados.

Caso tenha alguma dúvida ou sugestão, deixe abaixo nos comentários. Se você estiver tentando usar a Realtime Database e teve um problema, coloque ele no StackOverflow, explicando o que você fez e qual foi o erro que teve. De certeza que você obterá ajuda de mim ou de alguém da comunidade. 🙂

--

--

Rosário Pereira Fernandes
GDG Maputo

Firebase DevRel Engineer at Google … Views and Opinions are my own.