Android
+
Firebase
Bruno de Lima e Silva
google.com/+BrunoDeLimaS
Gamer
Pós-graduado
Parto Humanizado
Crowdmobi
Trakto
Coding Dojo
# O que é Firebase?
● Banco de Dados Real-time
● Autenticação
● Desenvolvimento rápido
● Foco no usuário
● Bibliotecas para várias plataformas
# Como o Firebase funciona?
●Uma ávore JSON
● Sem registros
● Novo objeto = Novo campo em um JSON
● Valores monitorados
● Por que “monitorar” um valor?
# Intro Android
● Estrutura do projeto
● Layout e Widgets
● Java, Activity, Fragment
● Resouces Qualifiers (orientation, locale, screenSize)
# What do we need
● Git
● JDK
● Android SDK
● Android Studio
● GenyMotion*
Time to hit “next” *Emulador do android
Firebase
## Biblioteca
● Com o gradle é muito simles
● Adicione essa dependência
● Clique em Gradle Sync
dependencies {
compile 'com.firebase:firebase-client-android:2.3.1'
}
## Biblioteca
● Em alguns casos, adicione
android {
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE-FIREBASE.txt'
exclude 'META-INF/NOTICE'
}
}
## Permissões
● Internet
Só isso mesmo
<uses-permission android:name="android.permission.INTERNET" />
## Inicialização
● O firebase precisa ser iniciado com um context
● Iniciar na classe Application
● Pode ser na activity, se você só tiver uma.
● Deve acontecer antes de qualquer operação com o
firebase.
## Inicialização
Seu código deve ficar mais ou menos assim.
public class Application extends android.app.Application {
@Override
public void onCreate() {
super.onCreate();
Firebase.setAndroidContext(this);
}
}
# Salvando
● Existem várias formas
● Cada uma com seu propósito
● Cada operação precisa de uma referência
Firebase ref = new Firebase("sua-url-aqui");
## setValue()
● A Mais comum
● Escreve ou sobrescreve um valor
Firebase userRef = ref.child("users").child("gdgmaceio");
userRef.child("name").setValue("GDG Maceió");
userRef.child("birthYear").setValue(2014);
## setValue()
O código anterior criou a seguinte estrutura.
## setValue()
Podemos passar um objeto.
public class User {
private int birthYear;
private String name;
...
}
Firebase userRef = ref.child("users").child("gdgmaceio");
User user = new User("GDG Maceió", 2014);
userRef.setValue(user);
## setValue()
O código anterior também pode ser substituído por um
map.
Firebase userRef = ref.child("users").child("gdgmaceio");
Map<String, String> userMap = new HashMap<String, String>();
userMap.put("birthYear", "2014");
userMap.put("name", "GDG Maceió");
userRef.setValue(userMap);
## updateChildren()
● Atualiza apenas os nós alterados
● Usar pra editar múltiplos campos de simultaneamente
Firebase userRef = ref.child("users").child("gdgmaceio");
Map<String, Object> userMap = new HashMap<String, Object>();
nickname.put("name", "GDG Maceió Rocks!");
userMap.put("birthYear", "2013");
userRef.updateChildren(userMap);
## push()
● Usado para Listas
● Gerador de Identificador Único
Firebase chats = ref.child("chats");
Map<String, String> post1 = new HashMap<String, String>();
post1.put("author", "brunodles");
post1.put("message", "Android Is Awesome");
chats.push().setValue(post1);
## push()
● Para adicionar o um segundo post
Map<String, String> post2 = new HashMap<String, String>();
post2.put("author", "gdgmaceio");
post2.put("message", "Firebase too! o/");
chats.push().setValue(post2);
## runTransaction()
● Quando usar
○Operações concorrentes
○Possibilidade de inconsistência de dados
● Implementação diferente
## runTransaction()ref.child("chatCount").runTransaction(new Transaction.Handler() {
@Override
public Transaction.Result doTransaction(MutableData currentData) {
if (currentData.getValue() == null) {
currentData.setValue(1);
} else {
currentData.setValue((Long) currentData.getValue() + 1);
}
return Transaction.success(currentData);
//we can also abort by calling Transaction.abort()
}
@Override
public void onComplete(FirebaseError firebaseError, boolean committed, DataSnapshot currentData) {
//This method will be called once with the results of the transaction.
}
});
# Monitorando Dados
● Implementar Interface
● Observer
● Várias formas de observar
## Eventos
Os eventos são disparados de acordo com alguma ação
dentro da referência atual.
● Adicionar
● Alterar
● Remover
### Value
● Monitora todas alterações
● Primeira chama é o estado atual
● Chamadas seguintes são atualizações
● Sempre retorna estrutura interna completa
ref.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
}
@Override
public void onCancelled(FirebaseError firebaseError) {
}
});
#### Child Added
● Monitora os filhos
● Usado para listas
● Chamado uma vez para cada filho
ref.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot snapshot, String previousChildKey) {
}
});
#### Child Changed
● Monitora alteração dos Filhos
● Usado em conjunto com childAdded
● Chamado para alteração dos filhos ou descendentes
ref.addChildEventListener(new ChildEventListener() {
@Override
public void onChildChanged(DataSnapshot snapshot, String previousChildKey) {
}
});
#### Child Removed
● Monitora remoção dos Filhos
● Usado em conjunto com childAdded e childChanged
● Recebe uma cópia do filho que foi removido
ref.addChildEventListener(new ChildEventListener() {
@Override
public void onChildRemoved(DataSnapshot snapshot) {
}
});
## Queries
● Ordenação
● Limites
Query query = ref.child("chats").orderByChild("date");
Firedroid
https://github.com/brunodles/Firedroid-gdg
1_ Criar projeto
1_ Criar projeto
1_ Criar projeto
1_ Criar projeto
1_ Criar projeto
2_ Importe o Firebase
dependencies {
compile 'com.firebase:firebase-client-android:2.3.1'
}
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE-FIREBASE.txt'
exclude 'META-INF/NOTICE'
}
● Importe usando o gradle
● Adicione para evitar possíveis conflitos
3_ Permissão de Internet
● Adicione no AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
4_ Inicialize o Firebase
● Crie uma nova classe java chamada Application
● Faça ela herdar de android.app.Application
● Sobrescreva o método onCreate
● Inicialize o Firebase
● Use essa classe como name da tag Application no
AndroidManifest.xml
4_ Inicialize o Firebase
public class Application extends android.app.Application {
@Override
public void onCreate() {
super.onCreate();
Firebase.setAndroidContext(this);
}
}
<application
android:name=".Application"
5_ Classe auxiliar
● Essa classe vai ajudar a acessar o Firebase
● Pode evoluir pra um Data Access Object
public class FirebaseHelper {
public static Firebase get() {
return new Firebase("https://firedroid.firebaseio.com/");
}
}
É possível colocar essa string em outros arquivos, deixando a compilação mais dinâmica.
6_ Login
● Adicionar ao layout
○ Campos de texto
■Email
■Password
○ Botões
■Sign In
■ Sign UP
■Forgot password
6_ Login
● Associar os campos no fragment
● Criar
○Click Listener para os botões
○registro de usuário
○login de usuário
○recuperar senha
● remover menu
Existe uma lib para fazer essas associações de forma mais elegante.
7_ Chat
● Montar tela do chat
○ TextView
○EditText
○Button
● Associar widgets
● Iniciar após o Login
● Enviar mensagem
7_ Chat
Firebase firebase = FirebaseHelper.get();
Firebase messageRef = firebase.child("messages").push();
messageRef.child("text").setValue(message.getText().toString());
7_ Chat
● Exibir todas as mensagems no TextView
● Usando o Value Event Listener
Depois vamos mudar isso, para um ListView
Iterable<DataSnapshot> children = dataSnapshot.getChildren();
StringBuilder builder = new StringBuilder();
for (DataSnapshot child : children) {
builder.append(child.child("text").getValue());
builder.append("n");
}
messages.setText(builder.toString());
8_ Melhorar Login
● Travar tela (Progress dialog)
● Logar usuário depois de registrar
● Guardar dados de login
9_ Melhorar Chat
● Enviar mensagem direto do teclado
● Limpar texto atual
● Colocar ListView no Layout
● Layout dos itens
● Adapter
● Mover para última messagem
10_ Melhorar Código
● Organizar classes
● Criar Classe Mensagem
● Helper para referencia de mensagem
● Enviar mensagem usando helper
● Extrair Login Preference
11_ Libs
● ButterKnife¹
● SnackBar (DesignCompat)²
¹ Remover “findViewById” e “Click Listeners”
compile 'com.jakewharton:butterknife:7.0.1'
compile 'com.android.support:design:22.2.1'
² Substituir Toast
Obrigado
+BrunoDeLimaS
Bruno de Lima
@brunodles

Android Firebase

  • 1.
  • 2.
    Bruno de Limae Silva google.com/+BrunoDeLimaS Gamer Pós-graduado Parto Humanizado Crowdmobi Trakto Coding Dojo
  • 3.
    # O queé Firebase? ● Banco de Dados Real-time ● Autenticação ● Desenvolvimento rápido ● Foco no usuário ● Bibliotecas para várias plataformas
  • 4.
    # Como oFirebase funciona? ●Uma ávore JSON ● Sem registros ● Novo objeto = Novo campo em um JSON ● Valores monitorados ● Por que “monitorar” um valor?
  • 5.
    # Intro Android ●Estrutura do projeto ● Layout e Widgets ● Java, Activity, Fragment ● Resouces Qualifiers (orientation, locale, screenSize)
  • 6.
    # What dowe need ● Git ● JDK ● Android SDK ● Android Studio ● GenyMotion* Time to hit “next” *Emulador do android
  • 7.
  • 8.
    ## Biblioteca ● Como gradle é muito simles ● Adicione essa dependência ● Clique em Gradle Sync dependencies { compile 'com.firebase:firebase-client-android:2.3.1' }
  • 9.
    ## Biblioteca ● Emalguns casos, adicione android { packagingOptions { exclude 'META-INF/LICENSE' exclude 'META-INF/LICENSE-FIREBASE.txt' exclude 'META-INF/NOTICE' } }
  • 10.
    ## Permissões ● Internet Sóisso mesmo <uses-permission android:name="android.permission.INTERNET" />
  • 11.
    ## Inicialização ● Ofirebase precisa ser iniciado com um context ● Iniciar na classe Application ● Pode ser na activity, se você só tiver uma. ● Deve acontecer antes de qualquer operação com o firebase.
  • 12.
    ## Inicialização Seu códigodeve ficar mais ou menos assim. public class Application extends android.app.Application { @Override public void onCreate() { super.onCreate(); Firebase.setAndroidContext(this); } }
  • 13.
    # Salvando ● Existemvárias formas ● Cada uma com seu propósito ● Cada operação precisa de uma referência Firebase ref = new Firebase("sua-url-aqui");
  • 14.
    ## setValue() ● AMais comum ● Escreve ou sobrescreve um valor Firebase userRef = ref.child("users").child("gdgmaceio"); userRef.child("name").setValue("GDG Maceió"); userRef.child("birthYear").setValue(2014);
  • 15.
    ## setValue() O códigoanterior criou a seguinte estrutura.
  • 16.
    ## setValue() Podemos passarum objeto. public class User { private int birthYear; private String name; ... } Firebase userRef = ref.child("users").child("gdgmaceio"); User user = new User("GDG Maceió", 2014); userRef.setValue(user);
  • 17.
    ## setValue() O códigoanterior também pode ser substituído por um map. Firebase userRef = ref.child("users").child("gdgmaceio"); Map<String, String> userMap = new HashMap<String, String>(); userMap.put("birthYear", "2014"); userMap.put("name", "GDG Maceió"); userRef.setValue(userMap);
  • 18.
    ## updateChildren() ● Atualizaapenas os nós alterados ● Usar pra editar múltiplos campos de simultaneamente Firebase userRef = ref.child("users").child("gdgmaceio"); Map<String, Object> userMap = new HashMap<String, Object>(); nickname.put("name", "GDG Maceió Rocks!"); userMap.put("birthYear", "2013"); userRef.updateChildren(userMap);
  • 19.
    ## push() ● Usadopara Listas ● Gerador de Identificador Único Firebase chats = ref.child("chats"); Map<String, String> post1 = new HashMap<String, String>(); post1.put("author", "brunodles"); post1.put("message", "Android Is Awesome"); chats.push().setValue(post1);
  • 20.
    ## push() ● Paraadicionar o um segundo post Map<String, String> post2 = new HashMap<String, String>(); post2.put("author", "gdgmaceio"); post2.put("message", "Firebase too! o/"); chats.push().setValue(post2);
  • 21.
    ## runTransaction() ● Quandousar ○Operações concorrentes ○Possibilidade de inconsistência de dados ● Implementação diferente
  • 22.
    ## runTransaction()ref.child("chatCount").runTransaction(new Transaction.Handler(){ @Override public Transaction.Result doTransaction(MutableData currentData) { if (currentData.getValue() == null) { currentData.setValue(1); } else { currentData.setValue((Long) currentData.getValue() + 1); } return Transaction.success(currentData); //we can also abort by calling Transaction.abort() } @Override public void onComplete(FirebaseError firebaseError, boolean committed, DataSnapshot currentData) { //This method will be called once with the results of the transaction. } });
  • 23.
    # Monitorando Dados ●Implementar Interface ● Observer ● Várias formas de observar
  • 24.
    ## Eventos Os eventossão disparados de acordo com alguma ação dentro da referência atual. ● Adicionar ● Alterar ● Remover
  • 25.
    ### Value ● Monitoratodas alterações ● Primeira chama é o estado atual ● Chamadas seguintes são atualizações ● Sempre retorna estrutura interna completa ref.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot snapshot) { } @Override public void onCancelled(FirebaseError firebaseError) { } });
  • 26.
    #### Child Added ●Monitora os filhos ● Usado para listas ● Chamado uma vez para cada filho ref.addChildEventListener(new ChildEventListener() { @Override public void onChildAdded(DataSnapshot snapshot, String previousChildKey) { } });
  • 27.
    #### Child Changed ●Monitora alteração dos Filhos ● Usado em conjunto com childAdded ● Chamado para alteração dos filhos ou descendentes ref.addChildEventListener(new ChildEventListener() { @Override public void onChildChanged(DataSnapshot snapshot, String previousChildKey) { } });
  • 28.
    #### Child Removed ●Monitora remoção dos Filhos ● Usado em conjunto com childAdded e childChanged ● Recebe uma cópia do filho que foi removido ref.addChildEventListener(new ChildEventListener() { @Override public void onChildRemoved(DataSnapshot snapshot) { } });
  • 29.
    ## Queries ● Ordenação ●Limites Query query = ref.child("chats").orderByChild("date");
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
    2_ Importe oFirebase dependencies { compile 'com.firebase:firebase-client-android:2.3.1' } packagingOptions { exclude 'META-INF/LICENSE' exclude 'META-INF/LICENSE-FIREBASE.txt' exclude 'META-INF/NOTICE' } ● Importe usando o gradle ● Adicione para evitar possíveis conflitos
  • 37.
    3_ Permissão deInternet ● Adicione no AndroidManifest.xml <uses-permission android:name="android.permission.INTERNET" />
  • 38.
    4_ Inicialize oFirebase ● Crie uma nova classe java chamada Application ● Faça ela herdar de android.app.Application ● Sobrescreva o método onCreate ● Inicialize o Firebase ● Use essa classe como name da tag Application no AndroidManifest.xml
  • 39.
    4_ Inicialize oFirebase public class Application extends android.app.Application { @Override public void onCreate() { super.onCreate(); Firebase.setAndroidContext(this); } } <application android:name=".Application"
  • 40.
    5_ Classe auxiliar ●Essa classe vai ajudar a acessar o Firebase ● Pode evoluir pra um Data Access Object public class FirebaseHelper { public static Firebase get() { return new Firebase("https://firedroid.firebaseio.com/"); } } É possível colocar essa string em outros arquivos, deixando a compilação mais dinâmica.
  • 41.
    6_ Login ● Adicionarao layout ○ Campos de texto ■Email ■Password ○ Botões ■Sign In ■ Sign UP ■Forgot password
  • 42.
    6_ Login ● Associaros campos no fragment ● Criar ○Click Listener para os botões ○registro de usuário ○login de usuário ○recuperar senha ● remover menu Existe uma lib para fazer essas associações de forma mais elegante.
  • 43.
    7_ Chat ● Montartela do chat ○ TextView ○EditText ○Button ● Associar widgets ● Iniciar após o Login ● Enviar mensagem
  • 44.
    7_ Chat Firebase firebase= FirebaseHelper.get(); Firebase messageRef = firebase.child("messages").push(); messageRef.child("text").setValue(message.getText().toString());
  • 45.
    7_ Chat ● Exibirtodas as mensagems no TextView ● Usando o Value Event Listener Depois vamos mudar isso, para um ListView Iterable<DataSnapshot> children = dataSnapshot.getChildren(); StringBuilder builder = new StringBuilder(); for (DataSnapshot child : children) { builder.append(child.child("text").getValue()); builder.append("n"); } messages.setText(builder.toString());
  • 46.
    8_ Melhorar Login ●Travar tela (Progress dialog) ● Logar usuário depois de registrar ● Guardar dados de login
  • 47.
    9_ Melhorar Chat ●Enviar mensagem direto do teclado ● Limpar texto atual ● Colocar ListView no Layout ● Layout dos itens ● Adapter ● Mover para última messagem
  • 48.
    10_ Melhorar Código ●Organizar classes ● Criar Classe Mensagem ● Helper para referencia de mensagem ● Enviar mensagem usando helper ● Extrair Login Preference
  • 49.
    11_ Libs ● ButterKnife¹ ●SnackBar (DesignCompat)² ¹ Remover “findViewById” e “Click Listeners” compile 'com.jakewharton:butterknife:7.0.1' compile 'com.android.support:design:22.2.1' ² Substituir Toast
  • 50.

Notas do Editor

  • #3 Sou Gamer, foi isso que me trouxe pra o mundo dá programação. Sou pós-graduado em desenvolvimento para dispositivos móveis. Em um hackathon montamos o parto humanizado. Trabalhei na Ilhasoft desenvolvendo o crowdmobi e outros projetos. Hoje trabalho no Trakto. com Android, Api e Web. Sou organizador do Maceió Coding Dojo.
  • #4 Basicamente é um banco de dados real-time, mas não é só isso. Além de guardar e sincronizar os dados, também é possível fazer autenticação de forma simples, integrada com vários serviços. A ideia principal é prover um desenvolvimento rápido para ajudar os desenvolvedores a forcar no usuário. Já existem bibliotecas para maior parte das plataformas.
  • #5 Tudo é JSON. A ideia é guardar tudo em uma árvore JSON. Não existe necessidade de tabelas registros. Ao adicionar um objeto você está apenas adicionando um novo campo em um JSON. Para monitorar um valor é só informar a KEY. Por que “monitorar”, bom como a ideia é ser real-time então não solicitamos um valor, nós ficamos escutando as alterações desse valor. Sempre que ele é alterado um método é chamado para informa a alteração.
  • #6 Mostrar no Android Studio
  • #9 Para começar a usar é muito simples, basta adicionar a linha abaixo as dependências do arquivo ´build.gradle´ do app.
  • #10 Também adicione essas linhas abaixo por precaução. Isso vai fazer com que os esses arquivos sejam excluídos dos pacotes, para evitar erros durante a compilação.
  • #11 Ainda é necessário adicionar a permissão de internet, caso ainda não exista. Para isso adicione a linha abaixo no `AndroidManifest.xml`.
  • #12 Para finalizar nossa instalação é necessário inicializar o firebase. É recomendado inicializar a lib no método `onCreate` da sua classe `application`. Caso não tenha e não queria criar a classe, pode ser no método `onCreate` da primeira `activity`. Só uma alerta: essa inicialização deve acontecer antes de qualquer operação com o firebase.
  • #14 Existem várias formas de salvar dados, cada uma com o seu propósito. Para todas as operações será necessário ter uma referencia do banco.
  • #15 A mais comum, escreve ou sobrescreve um valor no caminho informado.
  • #18 Ainda é possível substituir o código acima por *HashMap* e passar as informações usando *key-value*.
  • #19 Atualiza filhos sem sobrescrever o resto do conteúdo, ou seja, atualiza apenas os nós alterados. Só precisa ser usado caso haja necessidade de alterar vários campos de uma vez, caso contrario é recomendado usar o `setValue`.
  • #20 O `push `é muito interessante pois é a forma de trabalhar com listas e gerar identificadores únicos com o firebase.
  • #21 Para utilizar é muito simples, após chegar na referência do nó desejado é só chamar o método `push()`. Isso irá gerar uma nova referência com um novo *id*.
  • #22 Em algum ponto, pode ser necessário se preocupar com alterações concorrente. Em caso mal implementado iriam gerar dados corrompidos ou imprecisos. Para evitar isso iniciamos uma `transaction`, dessa forma o firebase garante que essa operação está pronta para concorrência. O funcionamento da transaction é um pouco diferente. Pra isso é necessário implementar o método `doTransaction` de um `Transaction.Handler`.
  • #24 Para recuperar os objetos é necessário implementar a interface que observa as alterações dos objetos. Assim como existem várias formas de salvar existem varias formas de observar os objetos.
  • #26 Esse evento monitora alterações de um caminho específico. A primeira chamada desse evento representa o estado atual do banco. As chamadas seguintes são alterações que foram realizadas. Todas as chamadas retorna toda a estrutura interna do caminho informado.
  • #27 Esse evento monitora os filhos, normalmente é usado para listas. Esse evento é chamado uma vez para cada filho do caminho informado.
  • #28 Monitora o evento de alteração dos filhos do caminho informado. Normalmente usado em conjunto com o `childAdded` e `childRemoved`. É chamado para alterações dos filhos ou descendentes.
  • #29 Monitora remoção dos filhos. Recebe uma “cópia” do filho que foi removido.
  • #30 Com queries é possível fazer consultas/buscas baseadas em vários fatores. Apartir da referência desejada especifique como deseja ordenar os dados, usando uma das funções: `orderByChild`, `orderByKey`, `orderByValue` ou `orderByPriority`.
  • #51 Quem gostou clica no “GOSTEI”. Se inscreve no canal. Me segue nas redes sociais. E é isso ai galera. Valeu, Falooooooou.