Vous êtes sur la page 1sur 14

1- Overview 

 
Neste curso, voce vai implementar um chat para app android e monitorar sua performance 
usando o firebase.   
 
O que você irá aprender: 
● Permitir que o usuario se inscreva 
● Sincronizar dados usando o Firebase REaltime Database 
● Receber mensagens em background com Firebase Notiffications 
● Configurar uma aplicaçãlo com Firebase Remote Config 
● Testar seu app com o Firebase Test Lab 
O que você vai precisar:
● Android Studio​ version 2.1+. 
● Codigo de Exemplo 
● Um device de teste com Android 2.3+ e Google Play services 9.8 ou mais atual, ou um 
emulador com Google Play services 9.8 ou mais atual 
● Se usar um device, um cabo de conexão 
 
2- Baixar código de exemplo 
https://drive.google.com/file/d/1ELHYP0PD7ChVG7n521_QDSrm9Q7erNMn/view?usp=shar
ing 
 
3-​ No Android Studio, selecione android-start do download de codigos de exemplo 
(File > Open > .../firebase-codelabs/android-start). 
 
4- Crie um projeto no firebase console 
 
1. Va ate o ​Firebase console​. 
2. Selecione Criar Novo Projeto,e nomeie seu projeto "FriendlyChat." 

Conectar seu app android 


1. Da tela de overwiew do seu novo projeto, 
2. clique em Add Firebase ao seu Android app. 
3. Insira o nome do pacote: ​com.google.firebase.codelab.friendlychat​. 

Adicione o arquivo google-services.json ao seu app 


Baixe e copie o arquivo google-services.json para o diretorio ​app ​no seu projeto. 

Adicione google-services plugin to your app 


O plugin google-services usa o google-services.json para configurar sua aplicação para usar o 
firebase. 
 
 
A linha seguinte já deve estar adicionada ao final do arquivo build.gradle na pasta app do seu 
projeto (cheque para confirmar): 
apply plugin: ​'com.google.gms.google-services'

Sincronize seu projeto com os arquivos gradle 


Para garantir que todas as dependencias estão disponiveis no seu app, voce deve sincronizar 
seu projeto com os arquivos gradle. Selecione Sync Project with Gradle Files na barra de 

ferramentas do android studio ( )  


 
5- Rode pela primeira vez o seu app 
Agora que voce importou seu o projeto para o android studio e configurou o google-services 
plugin com o seu arquivo json, voce está pronto para rodar o seu codigo pela primeira vez.  
Conecte o device android e clique em R​ un ​na barra de ferramentas 
 
O app devera rodar no seu device, e neste ponto, voce deverá ver uma lista de mensagens vazia, 
e enviar e receber mensagens ainda não deverá funcionar.  
 
6- Ativar autenticação 
Vamos requisitar ao usuario que faça log in antes de ler ou postar mensagens no nosso app de 
mensagens. 

Firebase Realtime Database Rules 


O acesso ao seu Banco de Dados Firebase é configurado por uma série de regras escritas em 
linguagem de configuração JSON. 
Va até o seu projeto no console Firebase, selecione Banco de Dados, e então Regras. Confirme 
se as regras configuradas no banco se parecem com as seguintes: 
{
​"rules"​: {
​".read"​: ​"auth != null"​,
​".write"​: ​"auth != null"
}
}

Configure Authentication APIs 


Antes de sua aplicação poder acessar a API de Autenticação do Firebase você vai precisar 
ativvar isso: 
1. Navegue até F​ irebase console​ e selecione seu projeto 
2. Selecione Autenticação 
3. Selecione Metodo de Login 
4. Torne a opção Google ativa  
5. Salve as configurações 

Adicione a dependencia do Firebase Auth  


O firebase-auth perminte fácil gerenciamento de autenticação de usuarios que usam sua 
aplicação. Confirme a existência dessa dependência no seu arquivo ​app/build.gradle​. 
compile ​'com.google.firebase:firebase-auth:11.8.0'

Adicione as variaveis Auth na classe ​MainActivity​ class: 

MainActivity.java  
// Firebase instance variables
private​ ​FirebaseAuth​ mFirebaseAuth;
private​ ​FirebaseUser​ mFirebaseUser;

Cheque o usuário atual


Modifique ​MainActivity.java​ para enviar o usuário para a tela de login sempre que rodar o app e 
não estiver logado. 
Adicione as seguintes linhas ao método ​onCreate​ depois de inicializar ​mUsername​: 
 
MainActivity.java 
// Initialize Firebase Auth
mFirebaseAuth = ​FirebaseAuth​.getInstance();
mFirebaseUser = mFirebaseAuth.getCurrentUser();
if​ (mFirebaseUser == ​null​) {
​// Not signed in, launch the Sign In activity
startActivity(​new​ ​Intent​(​this​, ​SignInActivity​.​class​));
finish();
​return​;
} ​else​ {
mUsername = mFirebaseUser.getDisplayName();
​if​ (mFirebaseUser.getPhotoUrl() != ​null​) {
mPhotoUrl = mFirebaseUser.getPhotoUrl().toString();
}
}
Então adicione um novo case ao o
​ nOptionsItemSelected()​ para utilizar o botão de login: 
 
MainActivity.java 
​@Override
​public​ ​boolean​ onOptionsItemSelected(​MenuItem​ item) {
​switch​ (item.getItemId()) {
​case​ R.id.sign_out_menu:
mFirebaseAuth.signOut();
​Auth​.​GoogleSignInApi​.signOut(mGoogleApiClient);
mUsername = ANONYMOUS;
startActivity(​new​ ​Intent​(​this​, ​SignInActivity​.​class​));
finish();
​return​ ​true​;
​default​:
​return​ ​super​.onOptionsItemSelected(item);
}
}
Agora que temos toda a lógica de enviar o usuario à tela de login sempre que necessário 
precisamos implementar a tela de login para que os usuarios possam logar: 

Implementar a tela de login 

Abra o arquivo ​SignInActivity.java​. Um simples botão de login é usado para iniciar a 


autenticação. Nesse passo você vai implementar a logica para o login com a conta google e 
depois usar a conta google para autenticar com o firebase. 
Adicione uma instancia Auth na classe ​SignInActivity​: 
 
SignInActivity.java 
// Firebase instance variables
private​ ​FirebaseAuth​ mFirebaseAuth;
Então, edite o metodo o ​ nCreate()​ para inicializar o Firebase da mesma maneira que voce fez na 
MainActivity​: 
 
SignInActivity.java 
// Initialize FirebaseAuth
mFirebaseAuth = ​FirebaseAuth​.getInstance();
 
Proximo, inicialize o login com Google. Atualize o metodo onClick: 
 
SignInActivity.java 
@Override
public​ ​void​ onClick(​View​ v) {
​switch​ (v.getId()) {
​case​ R.id.sign_in_button:
signIn();
​break​;
}
}
 
Adicione o metodo signIn que apresenta o usuario com o Google Sign-In UI. 
 
SignInActivity.java 
private​ ​void​ signIn() {
​Intent​ signInIntent = ​Auth​.​GoogleSignInApi​.getSignInIntent(mGoogleApiClient);
startActivityForResult(signInIntent, RC_SIGN_IN);
}
 
Proximo, adicione o metodo onActivityResult na SignInActivity para tratar o resultado do login. 
Se o resultado do Google login for bem sucedido, use a conta para autenticar com o firebase. 
 
SignInActivity.java 
@Override
​public​ ​void​ onActivityResult(​int​ requestCode, ​int​ resultCode, ​Intent​ data) {
​super​.onActivityResult(requestCode, resultCode, data);

​// Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);


​if​ (requestCode == RC_SIGN_IN) {
​GoogleSignInResult​ result = ​Auth​.​GoogleSignInApi​.getSignInResultFromIntent(data);
​if​ (result.isSuccess()) {
​// Google Sign-In was successful, authenticate with Firebase
​GoogleSignInAccount​ account = result.getSignInAccount();
firebaseAuthWithGoogle(account);
} ​else​ {
​// Google Sign-In failed
​Log​.e(TAG, ​"Google Sign-In failed."​);
}
}
}

Adicione o metodo firebaseAuthWithGoogle para autenticar com a conta do google logada: 


 
SignInActivity.java 
private​ ​void​ firebaseAuthWithGoogle(​GoogleSignInAccount​ acct) {
​Log​.d(TAG, ​"firebaseAuthWithGooogle:"​ + acct.getId());
​AuthCredential​ credential = ​GoogleAuthProvider​.getCredential(acct.getIdToken(), ​null​);
mFirebaseAuth.signInWithCredential(credential)
.addOnCompleteListener(​this​, ​new​ ​OnCompleteListener​<​AuthResult​>() {
​@Override
​public​ ​void​ onComplete(​@NonNull​ ​Task​<​AuthResult​> task) {
​Log​.d(TAG, ​"signInWithCredential:onComplete:"​ + task.isSuccessful());

​// If sign in fails, display a message to the user. If sign in succeeds


​// the auth state listener will be notified and logic to handle the
​// signed in user can be handled in the listener.
​if​ (!task.isSuccessful()) {
​Log​.w(TAG, ​"signInWithCredential"​, task.getException());
​Toast​.makeText(​SignInActivity​.​this​, ​"Authentication failed."​,
​Toast​.LENGTH_SHORT).show();
} ​else​ {
startActivity(​new​ ​Intent​(​SignInActivity​.​this​, ​MainActivity​.​class​));
finish();
}
}
});
}

É isto Você implementou a autenticação usando uma conta google 

Teste seu Trabalho 


Rode o app no seu device. Voce deve imediatamenteser enviado para a tela de login. Clique no 
botão de login. Você deverá então ser enviado à tela de mensagens se tudo ocorrer bem. 
 
7- Leia mensagens 

Importe mensagens 
1. No seu projeto no console Firebase, selecione Database. 
2. no menu overflow do Database, selecione Import JSON. 
3. Navegue até o arquivo initial_messages.json na raiz do repositorio, e selecione-o. 
4. Clique em Import. 
Depois de importar o arquivo JSON, seu banco de dados deve se parecer com: 

root
messages
-K2ib4H77rj0LYewF7dP
text: ​"hello"
name: ​"anonymous"
-K2ib5JHRbbL0NrztUfO
text: ​"how are you"
name: ​"anonymous"
-K2ib62mjHh34CAUbide
text: ​"i am fine"
name: ​"anonymous"

Adicione as dependencias Firebase Realtime Database e Firebase Storage


No bloco de dependencias do arquivo app/build.gradle, as seguintes dependencias devem 
ser incluidas.: 

Depencias no app/build.gradle 
compile ​'com.google.firebase:firebase-database:11.8.0'
compile ​'com.google.firebase:firebase-storage:11.8.0'

Sincronize menssagens 
Adicione o codigo que sincroniza novas mensagens a UI do app. 
Inicialize o Firebase Realtime Database e adicione umlistener para ratar as mudanças feitas 
aos dados. Atualize o adaptador RecyclerView então novas mensagens poderão ser vistas. 
Adicione a variavel Database na classe ​MainActivity​: 

MainActivity.java 
// Firebase instance variables
private​ ​DatabaseReference​ mFirebaseDatabaseReference;
private​ ​FirebaseRecyclerAdapter​<​FriendlyMessage​, ​MessageViewHolder​>
mFirebaseAdapter;

Modifique o metodo ​onCreate​, troque ​mProgressBar.setVisibility(ProgressBar.INVISIBLE); 


pelo codigo defido abaixo. O codigo inicialmente adiciona todas as mensagens existentes e 
aguarda por novas entradas: 

MainActivity.java 
// New child entries
mFirebaseDatabaseReference = ​FirebaseDatabase​.getInstance().getReference();
SnapshotParser​<​FriendlyMessage​> parser = ​new​ ​SnapshotParser​<F
​ riendlyMessage​>() {
​@Override
​public​ ​FriendlyMessage​ parseSnapshot(​DataSnapshot​ dataSnapshot) {
​FriendlyMessage​ friendlyMessage =
dataSnapshot.getValue(​FriendlyMessage​.​class​);
​if​ (friendlyMessage != ​null​) {
friendlyMessage.setId(dataSnapshot.getKey());
}
​return​ friendlyMessage;
}
};

DatabaseReference​ messagesRef =
mFirebaseDatabaseReference.child(MESSAGES_CHILD);
​FirebaseRecyclerOptions​<​FriendlyMessage​> options =
​new​ ​FirebaseRecyclerOptions​.​Builder​<​FriendlyMessage​>()
.setQuery(messagesRef, parser)
.build();
mFirebaseAdapter = ​new​ ​FirebaseRecyclerAdapter​<​FriendlyMessage​,
MessageViewHolder​>(options) {
​@Override
​public​ ​MessageViewHolder​ onCreateViewHolder(​ViewGroup​ viewGroup, ​int​ i) {
​LayoutInflater​ inflater = ​LayoutInflater​.​from​(viewGroup.getContext());
​return​ ​new​ ​MessageViewHolder​(inflater.inflate(R.layout.item_message,
viewGroup, ​false​));
}

​@Override
​protected​ ​void​ onBindViewHolder(​final​ ​MessageViewHolder​ viewHolder,
​int​ position,
​FriendlyMessage​ friendlyMessage) {
mProgressBar.setVisibility(​ProgressBar​.INVISIBLE);
if​ (friendlyMessage.getText() != ​null​) {
viewHolder.messageTextView.setText(friendlyMessage.getText());
viewHolder.messageTextView.setVisibility(​TextView​.VISIBLE);
viewHolder.messageImageView.setVisibility(​ImageView​.GONE);
} ​else​ {
​String​ imageUrl = friendlyMessage.getImageUrl();
​if​ (imageUrl.startsWith(​"gs://"​)) {
​StorageReference​ storageReference = ​FirebaseStorage​.getInstance()
.getReferenceFromUrl(imageUrl);
storageReference.getDownloadUrl().addOnCompleteListener(
​new​ ​OnCompleteListener​<​Uri​>() {
​@Override
​public​ ​void​ onComplete(​@NonNull​ ​Task​<​Uri​> task) {
​if​ (task.isSuccessful()) {
​String​ downloadUrl = task.getResult().toString();
​Glide​.​with​(viewHolder.messageImageView.getContext())
.load(downloadUrl)
.​into​(viewHolder.messageImageView);
} ​else​ {
​Log​.w(TAG, ​"Getting download url was not successful."​,
task.getException());
}
}
});
} ​else​ {
​Glide​.​with​(viewHolder.messageImageView.getContext())
.load(friendlyMessage.getImageUrl())
.​into​(viewHolder.messageImageView);
}
viewHolder.messageImageView.setVisibility(​ImageView​.VISIBLE);
viewHolder.messageTextView.setVisibility(​TextView​.GONE);
}

viewHolder.messengerTextView.setText(friendlyMessage.getName());
if​ (friendlyMessage.getPhotoUrl() == ​null​) {

viewHolder.messengerImageView.setImageDrawable(​ContextCompat​.getDrawable(​MainActi
vity​.​this​,
R.drawable.ic_account_circle_black_36dp));
} ​else​ {
​Glide​.​with​(​MainActivity​.​this​)
.load(friendlyMessage.getPhotoUrl())
.​into​(viewHolder.messengerImageView);
}

}
};

mFirebaseAdapter.registerAdapterDataObserver(​new​ ​RecyclerView​.​AdapterDataObserver​()
{
​@Override
​public​ ​void​ onItemRangeInserted(​int​ positionStart, ​int​ itemCount) {
​super​.onItemRangeInserted(positionStart, itemCount);
​int​ friendlyMessageCount = mFirebaseAdapter.getItemCount();
​int​ lastVisiblePosition =
mLinearLayoutManager.findLastCompletelyVisibleItemPosition();
​// If the recycler view is initially being loaded or the
​// user is at the bottom of the list, scroll to the bottom
​// of the list to show the newly added message.
​if​ (lastVisiblePosition == -​1​ ||
(positionStart >= (friendlyMessageCount - ​1​) &&
lastVisiblePosition == (positionStart - ​1​))) {
mMessageRecyclerView.scrollToPosition(positionStart);
}
}
});

mMessageRecyclerView.setAdapter(mFirebaseAdapter);

Atualize os metodos ​onPause​ e o


​ nResume​ na MainActivity como mostrado abaixo: 

MainActivity.java 
@Override
public​ ​void​ onPause() {
mFirebaseAdapter.stopListening();
​super​.onPause();
}

@Override
public​ ​void​ onResume() {
​super​.onResume();
mFirebaseAdapter.startListening();
}

Teste a sincronização de mensagens: 

1. Clique em Run ( ). 


2. Adicione novas mensagens diretamente no Database no console Firebase. Confirme 
que elas são mostradas ns UI do app. 
● Na seção Database do console Firebase, Data tab, selecione o sinal '+' no elemento 
mensagens. 
● de ao elemento o nome -ABCD (note o sinal '-') 
● Selecione o sinal '+' no elemento -ABCD  
● De ao novo elemento o nome e o valor que desejarem (exemplo: seu nome) 
● Selecione o sinal '+' sign no elemento -ABCD  
● Dê ao novo elemento o nome de texto e o valor que quiser (Exemplo: olá) 
● Selecione ‘Adicionar’ 
Parabéns, você acabou de adicionar em tempo realao banco de dados do seu app! 
 
 

8. Envie Mensagens  
Implemente o ennvio de mensagens 
Nesta seção, você irá adicionar a funcionalidade de envio de mensagens para os usuários 
do seu app. O trecho de código abaixo espera por eventos de cliques no botão de enviar, cria 
um novo objeto ​FriendlyMessage​ com o conteúdo do campo de mensagem, e envia a 
mensagem ao banco de dados. O método push() adiciona um id auto gerado ao caminho do 
objeto enviado. Esses IDs são sequenciais o que garante que novas mensagenssejam 
adicionadas ao fim da lista. 
Atualize o método ​onClick​ de m
​ SendButton​ no método ​onCreate​ na classe M ​ ainActivity​. 
Este código já está no fim do método o​ nCreate​, atualize o corpo do o
​ nClick​ para encaixar 
com o código abaixo: 

MainActivity.java 
mSendButton = (​Button​) findViewById(R.id.sendButton);
mSendButton.setOnClickListener(​new​ ​View​.​OnClickListener​() {
​@Override
​public​ ​void​ onClick(​View​ view) {
​FriendlyMessage​ friendlyMessage = ​new
​FriendlyMessage​(mMessageEditText.getText().toString(),
mUsername,
mPhotoUrl,
​null​ ​/* no image */​);
mFirebaseDatabaseReference.child(MESSAGES_CHILD)
.push().setValue(friendlyMessage);
mMessageEditText.setText(​""​);
}
});
Implemente o envio de imagens nas mensagens 
Nesta seção, você irá adicionar a funcionalidade de envio de imagens no seu app. Os 
passos para enviar uma imagem são os seguintes: 
● Selecione uma imagem  
● Controle a seleção da imagem 
● Escreva a mensagem temporário no RTDB 
● Inicie o upload da imagem selecionada 
● Atualize a URL da mensagem para o da imagem upada, uma vez que o upload tenha 
terminado 
Selecione a imagem 
Com o seguinte trecho de código, você vai permitir que usuário selecione uma imagem do 
armazenamento local do seu aparelho. Atualize o método onClick de 
mAddMessageImageView​ no método onCreate na classe MainActivity. Este código já está 
no final do método o
​ nCreate​, atualize o corpo do o
​ nClick​ para encaixar o código abaixo. 

MainActivity.java 
mAddMessageImageView = (​ImageView​) findViewById(R.id.addMessageImageView);
mAddMessageImageView.setOnClickListener(​new​ ​View​.​OnClickListener​() {
​@Override
​public​ ​void​ onClick(​View​ view) {
​Intent​ intent = ​new​ ​Intent​(​Intent​.ACTION_OPEN_DOCUMENT);
intent.addCategory(​Intent​.CATEGORY_OPENABLE);
intent.setType(​"image/*"​);
startActivityForResult(intent, REQUEST_IMAGE);
}
});
Controle a imagem selecionada escreva uma mensagem temporária 
Uma vez que o usuário selecionou uma imagem, uma chamada ao método onActivityResult 
da MainActivity será disparada. Isto é onde você controla a imagem selecionada pelo 
usuário. Usando o trecho de código abaixo, e o método onActivityResult da MainActivity. 
Nesta função você irá escrever uma url de mensagem temporária ao banco de dados 
indicando que a imagem está sendo carregada. 

MainActivity.java 
@Override
protected​ ​void​ onActivityResult(​int​ requestCode, ​int​ resultCode, ​Intent​ data) {
​super​.onActivityResult(requestCode, resultCode, data);
​Log​.d(TAG, ​"onActivityResult: requestCode="​ + requestCode + ​", resultCode="​ +
resultCode);
​if​ (requestCode == REQUEST_IMAGE) {
​if​ (resultCode == RESULT_OK) {
​if​ (data != ​null​) {
​final​ ​Uri​ uri = data.getData();
​Log​.d(TAG, ​"Uri: "​ + uri.toString());

​FriendlyMessage​ tempMessage = ​new​ ​FriendlyMessage​(​null​, mUsername,


mPhotoUrl,
LOADING_IMAGE_URL);
mFirebaseDatabaseReference.child(MESSAGES_CHILD).push()
.setValue(tempMessage, ​new​ ​DatabaseReference​.​CompletionListener​() {
​@Override
​public​ ​void​ onComplete(​DatabaseError​ databaseError,
​DatabaseReference​ databaseReference) {
​if​ (databaseError == ​null​) {
​String​ key = databaseReference.getKey();
​StorageReference​ storageReference =
​FirebaseStorage​.getInstance()
.getReference(mFirebaseUser.getUid())
.child(key)
.child(uri.getLastPathSegment());

putImageInStorage(storageReference, uri, key);


} ​else​ {
​Log​.w(TAG, ​"Unable to write message to database."​,
databaseError.toException());
}
}
});
}
}
}
}
Carregue a imagem e atualize a mensagem 
Adicione o método putImageInStorage à MainActivity. Ele é chamado no onActivityResult 
para iniciar o upload da imagem selecionada. Uma vez que o upload for completado você irá 
atualizar a mensagem para usar a imagem apropriada. 
MainActivity.java 
private​ ​void​ putImageInStorage(​StorageReference​ storageReference, ​Uri​ uri, ​final​ ​String
key) {
storageReference.putFile(uri).addOnCompleteListener(​MainActivity​.​this​,
​new​ ​OnCompleteListener​<​UploadTask​.​TaskSnapshot​>() {
​@Override
​public​ ​void​ onComplete(​@NonNull​ ​Task​<​UploadTask​.​TaskSnapshot​> task) {
​if​ (task.isSuccessful()) {
​FriendlyMessage​ friendlyMessage =
​new​ ​FriendlyMessage​(​null​, mUsername, mPhotoUrl,
task.getResult().getMetadata().getDownloadUrl()
.toString());
mFirebaseDatabaseReference.child(MESSAGES_CHILD).child(key)
.setValue(friendlyMessage);
} ​else​ {
​Log​.w(TAG, ​"Image upload task was not successful."​,
task.getException());
}
}
});
}

Teste o envio de mensagens 

1. Clique no botão Run . 


2. Digite uma mensagem e clique no botão enviar, a nova mensagem deverá estar 
visível na UI do app e no console Firebase. 
3. Clique no sinal "+" para selecionar uma imagem. 

Nota: Nesta prática, Friendly Messages são limitadas ao tamanho de 10 caracteres.  

Vous aimerez peut-être aussi