Eventos de Leitura e Firebase UI Android - Parte 2

Investir em Você é Barra de Ouro a R$ 2,00. Cadastre-se e receba grátis conteúdos Android sem precedentes! Você receberá um email de confirmação. Somente depois de confirma-lo é que eu poderei lhe enviar os conteúdos semanais exclusivos. Os artigos em PDF são entregues somente para os inscritos na lista.

Email inválido.
Blog /Android /Eventos de Leitura e Firebase UI Android - Parte 2

Eventos de Leitura e Firebase UI Android - Parte 2

Vinícius Thiengo
(5209) (17)
Go-ahead
"O método consciente de tentativa e erro é mais bem-sucedido que o planejamento de um gênio isolado."
Peter Skillman
Prototipagem Android
Capa do curso Prototipagem Profissional de Aplicativos
TítuloAndroid: Prototipagem Profissional de Aplicativos
CategoriasAndroid, Design, Protótipo
AutorVinícius Thiengo
Vídeo aulas186
Tempo15 horas
ExercíciosSim
CertificadoSim
Acessar Curso
Quer aprender a programar para Android? Acesse abaixo o curso gratuito no Blog.
Lendo
TítuloManual de DevOps: como obter agilidade, confiabilidade e segurança em organizações tecnológicas
CategoriaEngenharia de Software
Autor(es)Gene Kim, Jez Humble, John Willis, Patrick Debois
EditoraAlta Books
Edição
Ano2018
Páginas464
Conteúdo Exclusivo
Investir em Você é Barra de Ouro a R$ 2,00. Cadastre-se e receba gratuitamente conteúdos Android sem precedentes!
Email inválido

Opa, blz?

Nesse vídeo dois da série Firebase no Android são apresentados os cinco eventos de leitura e o uso do Firebase UI para inserção de dados no RecyclerView de usuários do chat.

É apresentado também a vantagem que temos na atualização dos dados na APP quando a entidade ativa da comunicação é o servidor e não a APP. Com o Firebase não há necessidade da utilização de serviços de push message quando a APP está sendo utilizada. O Firebase se encarrega de informar (via mensagem no modelo broadcast) todos os devices que estão utilizando a APP.

Fique atento quanto aos listeners Value e Child, pois apesar do uso do ValueEventListener ser mais simples ele é também ineficiente.

No decorrer do post seguimos com o código do primeiro vídeo. O primeiro passo é atualizar o build.gradle (Module: app). A minTargetSDK é 16 agora, atualizamos a versão do compile do Firebase e inserimos o compile do Firebase UI:

apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"

defaultConfig {
applicationId "br.com.thiengo.thiengocalopsitafbexample"
minSdkVersion 16
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
repositories {
mavenCentral()
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.2.1'
compile 'com.android.support:design:23.2.1'
compile 'com.firebase:firebase-client-android:2.5.2+'
compile 'com.firebaseui:firebase-ui:0.3.1'
}

Nossa próxima atualização é no código da classe User.class, primeiro no método saveDB, onde depois da remoção das chamadas a setId() e setPassword() ficamos com o seguinte código:

...
public void saveDB(){
Firebase firebase = LibraryClass.getFirebase();
firebase = firebase.child("users").child( getId() );
firebase.setValue(this);
}
...

Logo acima da assinatura da classe definimos um annotation para ignorar os campos id e password na leitura e inserção de dados no Firebase utilizando um objeto (ou modelo de classe) do tipo User:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

...
@JsonIgnoreProperties({"id", "password"})
public class User {
...
}

Nosso próximo passo é atualizar o layout de nossa MainActivity.class, activity_main.xml. Foi removido o TextView e Button e adicionado um RecyclerView:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="br.com.thiengo.thiengocalopsitafbexample.MainActivity">

<android.support.v7.widget.RecyclerView
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:id="@+id/rv_users"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>

Agora seguimos com a atualização da classe MainActivity.class. Primeiro removemos o antigo método de logoff e adicionamos os métodos onCreateOptionsMenu() e onOptionsItemSelected():

...
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();

if(id == R.id.action_update){
startActivity(new Intent(this, UpdateActivity.class));
}
else if(id == R.id.action_logout){
firebase.unauth();

Intent intent = new Intent(this, LoginActivity.class);
startActivity(intent);
finish();
}

return super.onOptionsItemSelected(item);
}
...

Note que nossa lógica de logoff está no segundo condicional do método onOptionsItemSelected(), sem a referencia a nossa LibraryClass, pois firebase agora é uma variável de instância.

Uma pausa para colocarmos o menu.xml no folder /res/menu:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">

<item
android:id="@+id/action_update"
android:orderInCategory="100"
android:title="@string/atualizar"
app:showAsAction="never" />

<item
android:id="@+id/action_logout"
android:orderInCategory="100"
android:title="@string/logout"
app:showAsAction="never" />
</menu>

Agora voltando a MainActivity devemos definir firebase como variável de instância e implementar o novo código de onCreate():

...
private Firebase firebase;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

firebase = LibraryClass.getFirebase().child("users");
}
...

Agora implementamos um método init() que será responsável por inicializar nosso RecyclerView. Esse método será chamado no onResume():

...
@Override
protected void onResume() {
super.onResume();
init();
}

private void init(){
RecyclerView rvUsers = (RecyclerView) findViewById(R.id.rv_users);
rvUsers.setHasFixedSize( true );
rvUsers.setLayoutManager( new LinearLayoutManager(this));
}
...

Note que ainda não colocamos o adapter no RecyclerView. Essa parte será implementada posteriormente no post.

Na raiz do projeto, onde se encontram as Activities crie um novo package com o nome "listener". Agora criamos a primeira classe listener de teste. Antes é necessário informar que o FIrebase tem cinco eventos de leitura, vamos criar duas novas classes que juntas implementam esses cinco listeners de leitura. A classe CustomValueEventListener implementa o evento de leitura Value e a classe CustomChildEventListener implementa os outros quatro eventos de leitura, são eles: onChildAdded(), onChildChanged(), onChildRemoved() e onChildMoved(). Abaixo a implementação de CustomValueEventListener:

import android.util.Log;
import com.firebase.client.DataSnapshot;
import com.firebase.client.FirebaseError;
import com.firebase.client.ValueEventListener;
import br.com.thiengo.thiengocalopsitafbexample.domain.User;


public class CustomValueEventListener implements ValueEventListener {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {

for( DataSnapshot d : dataSnapshot.getChildren() ){
User u = d.getValue( User.class );

Log.i("log", "Name: "+u.getName());
Log.i("log", "Email: "+u.getEmail());
}
}

@Override
public void onCancelled(FirebaseError firebaseError) {}
}

Nosso objetivo com as classes de que implementam as interfaces de listeners, além de entender delas, é descobrir se alguma será útil para o fácil preenchimento de nosso RecyclerView. O método onDataChange() será chamado sempre que houver alguma atualização, inserção ou remoção no nodo do Firebase que estiver sendo utilizado. O método onDataChange() será também chamado na primeira execução do método que vincula essa classe listener ao Firebase. Essa primeira chamada também é verdade para o método onChildAdded() da classe que implementa a interface ChildEventListener.

Abaixo a imagem do nodo "users" que vamos utilizar como conteúdo em nosso código exemplo:

 

Ainda temos de implementar a CustomChildEventListener que tem os outros métodos listeners:

import android.util.Log;
import com.firebase.client.ChildEventListener;
import com.firebase.client.DataSnapshot;
import com.firebase.client.FirebaseError;
import br.com.thiengo.thiengocalopsitafbexample.domain.User;

public class CustomChildEventListener implements ChildEventListener {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
User u = dataSnapshot.getValue( User.class );
Log.i("log", "ADDED");
Log.i("log", "Name: "+u.getName());
Log.i("log", "Email: "+u.getEmail());
}

@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
User u = dataSnapshot.getValue( User.class );
Log.i("log", "CHANGED");
Log.i("log", "Name: "+u.getName());
Log.i("log", "Email: "+u.getEmail());
}

@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
User u = dataSnapshot.getValue( User.class );
Log.i("log", "REMOVED");
Log.i("log", "Name: "+u.getName());
Log.i("log", "Email: "+u.getEmail());
}

@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {}

@Override
public void onCancelled(FirebaseError firebaseError) {}
}

Note que em ambas implementações temos o método onCanceled() que é acionado quando há algum problema na leitura dos dados do Frebase por parte das classes listeners. O método onMoved() de CustomChildEventListener pode ser ignorado para o conteúdo desse post.

O parâmetro DataSnapshot en anbas as classes representa o último estado dos dados do Firebase, porém representa os dados de acordo com a granularidade dos listeners. O ValueEventListener recebe todos os dados abaixo do nodo "users" que está sendo utilizado, ou seja, se somente um dado do nodo "users" for atualizado todo o conteúdo de "users" será retornado no método onDataChange() pelo parâmetro DataSnapshot.

A granularidade de ChildEventLsistener é menor, no caso somente o nodo atualizado terá os dados retornados e não todo o conteúdo de "users".

Agora partimos para o primeiro teste utilizando somente a classe que implementa o listener ValueEventListener. O primeiro passo é atualizar o método onCreate() da MainActivity além de adicionar uma variável de instância nomeada customValueEventListener:

...
private Firebase firebase;
private CustomValueEventListener customValueEventListener;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

firebase = LibraryClass.getFirebase().child("users");
customValueEventListener = new CustomValueEventListener();
firebase.addValueEventListener( customValueEventListener );
}
...

O método addValueListener() adiciona a referência ao listener Value, porém também temos a opção de utilizar o método addListenerForSingleValueEvent() que ao invés de persistir com o listener enquanto ele não é removido do Firebase ou a APP é encerrada, esse método muda o comportamento de um ValueEventListener. Ele ativará o listener somente uma vez e logo depois o removerá do firebase.

Para podermos testar a utilização do listener ValueEventListener ainda falta a implementação do onDestroy() da MainActivity. Nesse método vamos remover o listener do firebase antes de destruir a Activity. Isso é também útil para que seja reduzida as chances de um OutOfMemoryException devido o aumento de memory leak na APP. Segue código:

...
@Override
protected void onDestroy() {
super.onDestroy();
firebase.removeEventListener( customValueEventListener );
}
...

Vou evitar a fadiga e não postarei a imagem da APP depois desse teste, pois o resultado já foi comentado anteriormente. Logo de inicio todos os dados do nodo "users" são apresentados e logo de pois, testando a atualização de somente um nodo abaixo de "users", todos os dados são noavemente retornados. Todos esse print é apresentado nos logs do AndroidStudio por meio da chamada a Log.i() em nosso código.

Para o teste com a classe que implementa o listener ChildEventListener apenas devemos alterar o nome Value por Child nas entidades adicionadas para o teste com a classe que implementa ValueEventListener, como abaixo:

...
private CustomChildEventListener customChildEventListener;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

firebase = LibraryClass.getFirebase().child("users");
customChildEventListener = new CustomChildEventListener();
firebase.addChildEventListener( customChildEventListener );
}
...

E no onDestroy():

...
@Override
protected void onDestroy() {
super.onDestroy();
firebase.removeEventListener( customChildEventListener );
}
...

A vantagem dessa implementação com ChildEventListener é que somente o nodo alterado é retornado em algum dos métodos listeners. Mesmo assim ela ainda não nos atende no objetivo de preencher nosso RecyclerView com o menor esforço possível, logo vamos para a utilização das classes de Firebase UI.

Nosso primeiro passo é a criação de um novo package chamado adapter. Esse package ficará no mesmo level que o package listener, no mesmo level das Activities.

Nosso segundo passo é a definição de uma classe que herda de RecyclerView.ViewHolder. Em nosso projeto é a classe UserViewHolder que ficará dentro de nosso novo package, adapter:

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;

public class UserViewHolder extends RecyclerView.ViewHolder {

public TextView text1;
public TextView text2;

public UserViewHolder(View itemView) {
super(itemView);
text1 = (TextView) itemView.findViewById(android.R.id.text1);
text2 = (TextView) itemView.findViewById(android.R.id.text2);
}
}

Os TextViews acima são referentes ao layout nativo android.R.layout.two_line_list_item que será informado na instanciação do adapter de nosso RecyclerView, lá na MainActivity.

O próximo passo é a criação de uma classe personalizada para ser o adapter, essa classe herdará de FirebaseRecyclerAdapter e também estará no package adapter:

import com.firebase.client.Query;
import com.firebase.ui.FirebaseRecyclerAdapter;
import br.com.thiengo.thiengocalopsitafbexample.domain.User;

public class UserRecyclerAdapter extends FirebaseRecyclerAdapter<User, UserViewHolder> {

public UserRecyclerAdapter(
Class<User> modelClass,
int modelLayout,
Class<UserViewHolder> viewHolderClass,
Query ref ){

super( modelClass, modelLayout, viewHolderClass, ref );
}

@Override
protected void populateViewHolder(
UserViewHolder userViewHolder,
User user, int i) {

userViewHolder.text1.setText( user.getName() );
userViewHolder.text2.setText( user.getEmail() );
}
}

Note que nessa precisamos definir o construtor, pois é nele que será passado o modelo de classe para deserialização dos dados do Firebase para um objeto POJO Java. O id do layout que será utilizado. O modelo de classe que implementa o ViewHolder e uma referência a Firebase (Query herda de Firebase). Esses parâmetros vão permitir que o trabalho pesado de apresentação e atualização do RecyclerView seja feito pelo Firebase UI.

O método populateViewHolder() apenas mapeia os dados nas views de UserViewHolder.

Nosso próximo passo é configurar a MainActivity para vincular esse novo adapter ao RecyclerView. No método init() e no método onDestroy() agora temos:

...
private void init(){
RecyclerView rvUsers = (RecyclerView) findViewById(R.id.rv_users);
rvUsers.setHasFixedSize( true );
rvUsers.setLayoutManager( new LinearLayoutManager(this));

adapter = new UserRecyclerAdapter(
User.class,
android.R.layout.two_line_list_item,
UserViewHolder.class,
firebase );
}

@Override
protected void onDestroy() {
super.onDestroy();
adapter.cleanup();
}
...

O método cleanup() é responsável por remover o listener de mudança de dados no Firebase, listener que já é adicionado pelo Firebase UI. Depois do teste temos:

Note que para atualização de dados não precisamos do apoio de scripts de push message, o Firebase server trabalha como parte ativa da comunicação entre server e APP além de disparar a atualização da base no formato Broadcast.

O projeto completo pode ser encontrado no GitHub: https://github.com/viniciusthiengo/nosso-chate

O projeto parte dois também é apresentado por completo no vídeo abaixo:

Abaixo a lista de posts / vídeos que podem lhe ajudar a compreender melhor o conteúdo desse post dois além de links úteis para acompanhar o conteúdo sobre Firebase:

RecyclerView, Material Design Android - Parte 2

PlayList sobre Firebase no canal Google Developers

GitHub do Firebase UI

Página da doc Firebase sobre Retriving Data, fonte do conteúdo de eventos de leitura desse post

Vlw

Investir em Você é Barra de Ouro a R$ 2,00. Cadastre-se e receba grátis conteúdos Android sem precedentes!
Email inválido

Relacionado

Monetizando Sua APP Android Com AppJolt no UninstallMonetizando Sua APP Android Com AppJolt no UninstallAndroid
Edicão de Imagem no Android Com Adobe Creative SDKEdicão de Imagem no Android Com Adobe Creative SDKAndroid
Utilizando BottomSheet Material Design no AndroidUtilizando BottomSheet Material Design no AndroidAndroid
Persistência Com Firebase Android - Parte 1Persistência Com Firebase Android - Parte 1Android

Compartilhar

Comentários Facebook

Comentários Blog (17)

Para código / script, coloque entre [code] e [/code] para receber marcação especifica.
Forneça seu nome válido.
Forneça seu email válido.
Forneça o comentário.
Enviando, aguarde...
Wagner (1) (0)
12/03/2017
Ola Thiengo!
Já fiz uma implementação do Push Messaging onde envio notificações de um sistema web para os dispositivos cadastrados no BD mysql. Como eu faço pra substituir essa aplicação pelo Firebase e continuar enviando as notificações do sistema web para os dispositivos android?
Responder
Vinícius Thiengo (0) (0)
16/03/2017
Wagner, tudo bem?

A versão mais atual de push message do Android é com o FCM (Firebase Cloud Messaging), em seu caso seria em modo Third-party Server.

Ainda não tenha essa versão, Third-party, apresentada aqui no Blog, logo, o conteúdo que recomendo é o da documentação: https://firebase.google.com/docs/cloud-messaging/server

O conteúdo indicado anteriormente está em português.

Caso queira um artigo mais completo, digo, envolvendo o código backend, veja o do Ravi: http://www.androidhive.info/2012/10/android-push-notifications-using-google-cloud-messaging-gcm-php-and-mysql/

Ainda não o li, mas pelo número de comentários e compartilhamentos, parece ser muito bom. Abraço.
Responder
27/11/2016
Fala Thiengo, blz? Parabéns pelo blog, ótimo tutorial.
Cara, to com um erro, estou usando teu tutorial como base para outra aplicação, e estou tentando alimentar um ReclycerView com os dados do firebase. Olhei o código atualizado no GitHub, e está igual o método que chama o ReclycerView. Porém ele não está aparecendo na tela, e tenho este retorno no Log:

E/RecyclerView: No adapter attached; skipping layout

Se puder ajudar agradeço. valeu
Responder
Vinícius Thiengo (0) (0)
29/11/2016
Grégori, tudo bem aqui.

Certifique-se de que a chamada ao RecyclerView está vindo dentro da Thread principal.

E se possível, realize a inicialização do RecyclerView (RecyclerView, LayoutManager e Adapter) no método onResyme().

Dê uma olhada nessa discussão também: http://stackoverflow.com/a/30581896/2578331

Abraço.
Responder
Grégori (1) (0)
30/11/2016
Cara, obrigado. Ajudou bastante. Abraços
Responder
Matheus Bed (1) (0)
10/06/2016
Boa tarde thiengo,quando eu click em um usuario da lista eu quero saber mais dados sobre esse esse usuario em outra activity, como eu implemento isso?.
Responder
Vinícius Thiengo (0) (0)
11/06/2016
Fala Matheus, blz?
Vc pode abrir um fragment ou uma outra Activity. Essa parte do projeto ainda não chegamos, não aqui no firebase. Mas em outras PlayLists do canal já fizemos esse script.

Assista aos vídeos indicados abaiso e veja se consegue prosseguir com seu projeto depois de visto os mesmos. Qualquer dúvida volte aqui. Abraço

http://www.thiengo.com.br/material-dialog-correcao-bug-statusbar-e-acoes-nos-fragments-material-design-android-parte-7

http://www.thiengo.com.br/design-support-library-e-collapsingtoolbarlayout-material-design-android-parte-11

Obs. : Se no primeiro vídeo já houver a abertura da Activity de Carro, esse já é o suficiente para ti.
Responder
16/05/2016
Thiengo, boa tarde.

De forma alguma consigo deixar o minSDK em 15?
A maioria dos tablets que possuo utilizando a API 15.
Responder
Vinícius Thiengo (1) (0)
18/05/2016
Fala Diogenes, blz? O FirebaseUI é minSdk 16, se removê-lo tende a passar sem problemas. Abraço
Responder
Diogenes (0) (0)
20/05/2016
Blz e por ai? Ok, consegui atualizar o tablet para a API 18, mudando a Room.. Tablet de 2012.

Com as novidades que saíram do Google IO essa semana, algumas partes do seus exemplos foram deprecados, você fará os próximos vídeos com essa atualização para o Firebase 2.0?

Os seus vídeos são ótimos man, bom trabalho! :)
Responder
Vinícius Thiengo (0) (0)
21/05/2016
Fala Diogenes, blz aqui.
Vou ter de atualizar, continuar com uma versão deprecated não da. Abraço
Responder
Jhoseph (1) (0)
25/04/2016
Esta dando erro olha só:

FATAL EXCEPTION: main
                                                                                           Process: com.jhoseph.ajchatfirebase.ajchatfirebase, PID: 14513
                                                                                           com.firebase.client.FirebaseException: Failed to bounce to type
                                                                                               at com.firebase.client.DataSnapshot.getValue(DataSnapshot.java:185)
                                                                                               at com.jhoseph.ajchatfirebase.ajchatfirebase.listener.CustomValueEventListener.onDataChange(CustomValueEventListener.java:18)
                                                                                               at com.firebase.client.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:56)
                                                                                               at com.firebase.client.core.view.DataEvent.fire(DataEvent.java:45)
                                                                                               at com.firebase.client.core.view.EventRaiser$1.run(EventRaiser.java:38)
                                                                                               at android.os.Handler.handleCallback(Handler.java:739)
                                                                                               at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                               at android.os.Looper.loop(Looper.java:135)
                                                                                               at android.app.ActivityThread.main(ActivityThread.java:5254)
                                                                                               at java.lang.reflect.Method.invoke(Native Method)
                                                                                               at java.lang.reflect.Method.invoke(Method.java:372)
                                                                                               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                                                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
                                                                                            Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "dce120a5-ffe2-4db2-bf09-8766a409f47b" (class com.jhoseph.ajchatfirebase.ajchatfirebase.domain.User), not marked as ignorable (2 known properties: , "email", "name"])
                                                                                               at [Source: java.io.StringReader@3562eaaa; line: 1, column: 42] (through reference chain: com.jhoseph.ajchatfirebase.ajchatfirebase.domain.User["dce120a5-ffe2-4db2-bf09-8766a409f47b"])
                                                                                               at com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:555)
                                                                                               at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:708)
                                                                                               at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1160)
                                                                                               at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:315)
                                                                                               at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)
                                                                                               at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888)
                                                                                               at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2034)
                                                                                               at com.firebase.client.DataSnapshot.getValue(DataSnapshot.java:183)
                                                                                               at com.jhoseph.ajchatfirebase.ajchatfirebase.listener.CustomValueEventListener.onDataChange(CustomValueEventListener.java:18) 
                                                                                               at com.firebase.client.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:56) 
                                                                                               at com.firebase.client.core.view.DataEvent.fire(DataEvent.java:45) 
                                                                                               at com.firebase.client.core.view.EventRaiser$1.run(EventRaiser.java:38) 
                                                                                               at android.os.Handler.handleCallback(Handler.java:739) 
                                                                                               at android.os.Handler.dispatchMessage(Handler.java:95) 
                                                                                               at android.os.Looper.loop(Looper.java:135) 
                                                                                               at android.app.ActivityThread.main(ActivityThread.java:5254) 
                                                                                               at java.lang.reflect.Method.invoke(Native Method) 
                                                                                               at java.lang.reflect.Method.invoke(Method.java:372) 
                                                                                               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 
                                                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 

Responder
Vinícius Thiengo (0) (0)
30/04/2016
Fala Joseph,
Se não me engano vc entrou em contato comigo tb pelo YouTube e esse problema foi resolvido por ti mesmo, certo? Abraço
Responder
06/04/2016
Olá Thiengo, espero que você esteja bem. ótima aula! venho aprendendo muito com você..

Eu estava pesquisando  e parece que as bibliotecas e triggers do Firebase apenas funcionam quando o client(no caso o aplicativo android) está ativo, então apenas quando o app estiver aberto que ele irá receber push notifications.
Você teria alguma dica sobre como trabalhar com push notifications com firebase quando  o app estiver fechado ?

eu achei essas alternativas mas honestamente nenhuma me parece muito viável:
-Usar um service pra sempre executar em background. tem o o problema do consumo de bateria, exceder limite de conexão de usuários e gasto de internet do usuário.
-Um AlarmManager para executar sync a cada X horas. problema de não receber atualizações rápido o suficiente, já q a ideia  em um app de mensagens por exemplo é q ao receber uma mensagem no banco ela já seja notificada ao cliente imediatamente.
-Usar algum outro serviço de push notification q complemente firebase(ouvi falar do pushover: https://zapier.com/zapbook/pushover/firebase/ ). tem o problema de ter que pagar por um outro serviço.
Responder
Vinícius Thiengo (0) (0)
08/04/2016
Fala Júlio Cezar, td tranquilo
É isso mesmo, utilizar um serviço de push message em paralelo, pode ser o GCM. A fadiga vai ser ter de implementa-lo, pois é um serviço independente do Firebase, logo não será possível aproveitar o código do Firebase. Não conheço o pushover, mas por ele ser pago não creio ser uma melhor escolha ante ao GCM somente para trabalho com push message e gratuito. Abraço
Responder
acruche (1) (0)
28/03/2016
muito bom o vídeo, aguardando os próximos.
Responder
28/03/2016
Maravilha, era isso que eu esta procurando.Obrigado
Responder