PRÉDIOS HISTÓRICOS DE ASSARÉ Prof. Francisco Leite.pdf
TDC2016POA | Trilha Banco de Dados - Firebase e Realm, o NoSQL ganha força no Android
1. Banco de Dados no
Mobile: Realm e
Firebase
Ricardo da Silva Ogliari
GDG
2. Um Pouco Sobre Mim
● Bacharel em Ciência da Computação;
● Especialista em Web - Inovacão e Tecnologia;
● MBA: Desenvolvimento de Jogos e Apps Mobile;
● Co-autor do Livro: Android do Básico ao Avançado - Ciência Moderna;
● Mobile Magazine;
● Desenvolvedor Android Bikoo/BovControl;
● Professor Especialização Senac e UPF. Professor Graduação UPF;
● Mais de 310 publicações;
● Fundador Things Hacker Team;
● 10 Nomes Open-Hardware 2013 - Revista iMasters;
4. Introdução
● Uso de Banco de Dados Relacional - SQLite;
● API padrão do Android - Presente desde o Android 1.0;
● Código pesado, principalmente para novatos na plataforma ou oriundos de
concorrentes, como iOS e wPhone;
● Só uma olhadinha rápida:
● https://developer.android.com/training/basics/data-storage/databases.html?hl=
pt-br
6. Realm
● Promete ser mais rápido que qualquer outra solução de ORM;
● Promete ser mais rápido que o SQLite puro;
● Mais simples e Mais rápido;
● Suporte para:
○ Java/Android
○ Objective-C;
○ Swift;
○ Xamarim;
○ React Native;
7. Instalação - Pré-Requisitos
● Não suporta Java a não ser no Android. Neste momento.
● Android Studio >= 1.5.1.
● Versão do JDK >= 7.
● Android Api Level 9 ou superior (Android 2.3 Gingerbread).
8. Configuração da Biblioteca
● Gradle a nível de projeto:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath
"io.realm:realm-gradle-plugin:<versao>"
}
}
10. Modelo De Dados
● Uma simples classe que herda de RealmObject;
● Anotação para detalhes importantes de um banco de dados relacional, como o
@PrimeryKey para chave primária;
● Documentação detalha outras anotações e tipos de dados:
https://realm.io/docs/java
11. Modelo De Dados
public class Task extends RealmObject{
@PrimaryKey
public String nome;
public String descricao;
public long termino;
public String local;
public boolean iniciada;
@Override
public String toString() {
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(termino);
int dia = cal.get(Calendar.DAY_OF_MONTH);
...
return "Nome: " + nome + "nDescrição: " + descricao + "nTérmino: " +
(dia < 10 ? "0" + dia : "" + dia) + "/" + …);
}
}
12. RealmConfiguration e Realm
● Necessária a criação de uma configuração para o Realm (Migração, Encriptação);
● Posteriormente cria-se a própria instância de Realm (Trabalha diretamente sobre
os dados);
● Indicado usar em uma classe que estende de Application;
public class CoreApplication extends Application{
public Realm realm;
@Override
public void onCreate() {
super.onCreate();
RealmConfiguration realmConfig = new RealmConfiguration.Builder(this).deleteRealmIfMigrationNeeded().build();
Realm.setDefaultConfiguration(realmConfig);
realm = Realm.getDefaultInstance();
}
}
13. Pesquisando Dados
● A classe Realm possui o método where que define o alvo das pesquisas;
● Depois, nos traz uma infinidade de métodos que espelham grande parte das
pesquisas com SQL;
● Métodos auxiliares do SQL como count e average também estão presentes;
● Perceba o uso do método Assíncrono. O changeListener recebe o resultado
da pesquisa.
@Override
protected void onCreate(Bundle savedInstanceState) {
...
RealmResults<Task> result = ((CoreApplication)getApplication()).realm.where(Task.class).findAllAsync();
result.addChangeListener(callback);
}
14. Pesquisando Dados
● O Listener possui um único método a ser sobrescrito;
● O RealResults<Task> se usado no mesmo contexto da instância de Realm, mantém o listener
ativo e registra qualquer mudança nos dados.
● O RealmResults também precisa ser único para manter o callback para futuras atualizações.
● Método sort para ordenação dos resultados;
public static RealmResults<Task> results;
private RealmChangeListener callback = new RealmChangeListener() {
public void onChange(Object element) {
results = (RealmResults<Task>) element;
results = results.sort("termino", Sort.ASCENDING);
listTasks.setAdapter(new ArrayAdapter<Task>(
MainActivity.this, android.R.layout.simple_list_item_1, results
)
);
}
};
15. Excluindo
● Usando a mesma instância de Realm da Application;
● Método executeTransaction é síncrono;
● Opção de trabalho assíncrono. Porém, neste caso obrigatoriamente, precisamos
usar a opção síncrona.
● Na própria instância RealmObject é possível chamar deleteFromRealm.
//só pode ser feito da mesma thread onde o objeto foi criado
((CoreApplication)getApplication()).realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
task.deleteFromRealm();
}
});
//results.deleteFirstFromRealm();
//results.deleteLastFromRealm();
16. Salvar Dados
● Executamos uma tarefa assíncrona;
● A assinatura do método recebe a implementação de um método de sucesso e de erro;
Task result = ((CoreApplication)getApplication()).realm.where(Task.class).equalTo("nome", key).findFirst();
saveTaskNome.setText(result.nome);
…
((CoreApplication)getApplication()).realm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm bgRealm) {
Task task = new Task();
task.nome = saveTaskNome.getText().toString();
...
bgRealm.copyToRealmOrUpdate(task);
}
}, new Realm.Transaction.OnSuccess() {
public void onSuccess() {}
}, new Realm.Transaction.OnError() {
public void onError(Throwable error) {}
});
18. O que é?
● Um set de ferramentas que auxiliam e agilizam o processo de
desenvolvimento de aplicativos móveis;
19. Detalhes
● Android;
● Web;
● iOS;
● Alguns serviços gratuitos, alguns pagos e, também tem serviços com o modelo
de cotas;
● Pré-Requisitos para Android:
○ Android 2.3 ou superior;
○ Google Play Services 9.0.2 ou superior;
○ O Google Play Services SDK;
○ Android Studio 1.5 ou Superior;
○ Um projeto Android Studio e seu package name;
20. Configuração no Android - Passo 1
● Acessar o console do Firebase: https://console.firebase.google.com.
28. Base de Dados
● Para inicializar a base de dados podemos gerar um JSON;
● Minha dica: Json Generator: http://www.json-generator.com/;
29. Base de Dados
● O Json Generator permite o download do arquivo .json;
● No console do Firebase apenas importe o arquivo:
30. Base de Dados
● Logo a estrutura dos objetos Json vai ficar visível;
● Todos os dados podem ser editados;
31. E o Android???
● Todo o segredo é usar as classes FirebaseDatabase e DatabaseReference para
criar uma conexão com um path do bando de dados NOSql.
compile 'com.google.firebase:firebase-database:9.0.2'
FirebaseDatabase refCurrent = FirebaseDatabase.getInstance();
DatabaseReference myRef = refCurrent.getReference("tarefas");
compile 'com.google.firebase:firebase-database:9.0.2'
32. Pesquisa de Dados e Realtime Database
● As pesquisas de dados são possíveis com métodos que simulam boa parte das
consultas sql: queries, order by, first, limit, dentre outros;
● Na query ou na referência, temos listeners que funcionam realtime;
Query query = myRef.orderByChild("termino");
query.addValueEventListener(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snap : dataSnapshot.getChildren()){
if (Integer.parseInt(snap.getKey()) > key){
key = Integer.parseInt(snap.getKey());
}
Task task = snap.getValue(Task.class);
}
}
public void onCancelled(DatabaseError databaseError) { }
}
33. Novos Dados
● Cria-se um novo filho na referência pai;
● Configuramos um valor para este filho que, pode ser a instância de uma classe
que espelha os objetos do JSON no banco de dados;
Task task = new Task();
task.nome = "Outra tarefa";
task.iniciada = false;
task.local = "Home";
task.termino = 22334455;
task.descricao = "Somente outra tarefa";
myRef.child("" + ++key).setValue(task);
34. Alteração de Dados
● Basta setar o valor de uma referência. Como nosso listener atua 100% do tempo
a própria interface da aplicação será atualizada;
…
tasks.get(position).termino = System.currentTimeMillis();
DatabaseReference refItem = refCurrent.getReference("tarefas/" + (position + 1));
refItem.setValue(tasks.get(position));
...
});
35. Remover Dados
● Basta configurar o valor de um filho para null;
● Ou ainda, de uma forma mais elegante, chamar o método removeValue
diretamente em uma referência;
…
DatabaseReference refItem = refCurrent.getReference("tarefas/" + (position + 1));
refItem.removeValue();
...
});
36. Conclusão
● O que é mesmo SQLiteOpenHelper;
● Opções rápidas e mais próximas ao código Java;
● Baixo custo e/ou grátis;