Firebase Database para Desenvolvedores SQL — Consistência de dados

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.

No artigo anterior, aprendemos sobre denormalização — uma técnica que consiste em duplicar dados para simplificar e reduzir queries. A denormalização pode ser uma óptima solução para facilitar leituras, mas pode trazer um problema: falta de consistência de dados.

Quando temos dados duplicados, temos de garantir que ao alterar um dado a sua “cópia” também seja alterada. Você deve estar a pensar que isso é simples e basta utilizar 2 setValues:

DatabaseReference ref1 = raiz.child("usuarios/1/nome");
DatabaseReference ref2 = raiz.child("estudantes/am/1/nome");
ref1.setValue("Rosa");
ref2.setValue("Rosa");

Embora isto funcione neste caso simples, como vamos fazer o mesmo se o Rosário estiver a participar em outros grupos de estudo? Como vamos saber quais são os grupos em que o Rosário participa?

Lookups

Lookups consistem em criar um nó (usuario_grupos) na base de dados onde armazenamos o id do usuário e os ids dos grupos em que ele participa:

DatabaseReference gruposRosario = raiz.child("usuarios_grupos/1");
DatabaseReference estudantes = raiz.child("estudantes");
gruposRosario.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Iterator i = dataSnapshot.getChildren().iterator();
while(i.hasNext()) {
DataSnapshot snap = (DataSnapshot) i.next();
estudantes.child(snap.getKey()).child(dataSnapshot.getKey()+"/nome").setValue("Rosa");
}
}
@Override
public void onCancelled(DatabaseError databaseError) {}
});

Esta técnica funciona perfeitamente se o Rosário estiver a participar em apenas 5 grupos. Mas se ele estiver em 50 ou 100 grupos, este processo pode levar bastante tempo. Tempo suficiente para o nosso usuário fechar a aplicação ou o dispositivo ficar sem carga. E continuamos a não ter dados consistentes. E para resolver isso, existe uma outra técnica que vamos ver a seguir.

Multi-path updates

Multi-path updates são operações tudo ou nada. Você começa uma série de operações e se uma das operações não for concluída com sucesso, todas as operações anteriores serão desfeitas. Isso significa que nenhuma operação pode ser deixada incompleta.

Para utilizar os multi-path updates, basta especificar todos os caminhos que devem ser actualizados e qual o novo valor utilizando um HashMap da seguinte forma:

Map updates = new HashMap();
updates.put("usuarios/1/nome", "Rosa");
updates.put("estudantes/pa/1/nome", "Rosa");
updates.put("estudantes/am/1/nome", "Rosa");
updates.put("estudantes/md/1/nome", "Rosa");
//depois basta fazer o update:
raiz.updateChildren(updates);

Como o método updateChildren() é do tipo Task, podemos adicionar um OnSuccessListener ou OnFailureListener para sabermos se a operação foi concluída com sucesso ou não.

Mas os multi-path updates possuem riscos!

O primeiro risco é a destruição de dados. Vários desenvolvedores, tanto experientes como iniciantes, cometem este erro várias vezes. Como isso pode acontecer?

Vamos supor que ao invés de utilizar updates.put(“estudantes/am/1/nome”, “Rosa”) , utilizassemos updates.put(“estudantes/am/1”, “Rosa”). Isto faria com que todo o objecto de id 1 seja eliminado e fique apenas a String “Rosa”. Então, tenha a certeza de que o caminho especificado está correcto, senão você pode eliminar toda a base de dados.

Espero que a série tenha sido de bom agrado, fácil de compreender e aprender. Porque este é o último artigo da série Firebase para Desenvolvedores SQL. :)

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.