Recuperação de Senha, Firebase Atualizado - Parte 8
(8336) (7)
CategoriasAndroid, Design, Protótipo
AutorVinÃcius Thiengo
VÃdeo aulas186
Tempo15 horas
ExercÃciosSim
CertificadoSim
CategoriaDesenvolvimento Web
Autor(es)Robert C. Martin
EditoraAlta Books
Edição1ª
Ano2023
Páginas416
Opa, blz?
Nesse post continuamos com a série Firebase Android, porém já com a versão atualizada do Firebase, versão que foi anunciada no Google I/O 2016.
Nesse post falamos um pouco das vantagens de definitivamente utilizar o Firebase como parte de seu arsenal no dev Android (IOS e Web também) e para não deixar nosso código parado acrescentamos uma simples funcionalidade, recuperação de acesso, útil caso o usuário tenha utilizado o método convencional de acesso a área restrita, email e senha.
Antes de prosseguir, você tem acesso ao passo a passo de migração do Firebase acessando o link: Migração Firebase Android
Para acesso ao conteúdo de nosso APP da série, atualizado, entre no GitHub: https://github.com/viniciusthiengo/nosso-chate
Obs. : O vídeo com o conteúdo dessa postagem passo a passo está no final do post.
Agora um pouco da importância de passar a utilizar o Firebase no dev, principalmente Android (em nosso caso). Com aproximadamente 3 anos de blog e nele falando mais sobre Android, recebo muitas mensagens de contato sobre problemas e ideias.
O que percebo nas mensagens?
Muitos developers Android não têm habilidades no lado remoto da aplicação, ou seja, no backend Web. No Backend Web? Isso, para trabalhar com push message (GCM), banco de dados remoto (MySQL, por exemplo) e principalmente a linguagem de programação no backend (PH, Java, Python, ...).
Ok, mas qual a finalidade de falar sobre essa limitação de alguns developers Andrdoid?
Na verdade a finalidade está em incentivar o estudo e uso mais aprofundado do Firebase, pois ele acaba com essa dependência do developer Android quanto ao backend Web.
O backend remoto vai continuar existindo, porém tudo controlado diretamente da APP, sem necessidade de configuração de servidor Apache, banco de dados relacional (outro grande gargalo quando a APP começa a crescer), lógica de programação com linguagem backend, gastos extras com escalabilidade de servidores remotos, ...
Sem sombra de dúvidas com a atualização do Firebase cobrindo partes que ainda nos forçavam a utilizar um backend remoto configurado por nós, o número de APPs com maior qualidade e com funcionalidades vistas antes somente em grandes APPs tende a aumentar.
O conteúdo do Firebase é tranquilo, diferente da migração ListView => RecyclerView, o conteúdo é simples e o controle complexo (quando conectado ou não a Internet, upload de mídia, funcionamento também quando offline, ...) da APP fica todo com o Firebase.
Então como dica: estude-o o quanto antes e a fundo, suas ideias de APPs, Startups, projetos científicos, ... tendem a aumentar em número e qualidade.
E sobre as versões pagas?
Se for necessário o uso de um plano pago isso pode ser um bom sinal, indica que sua APP está crescendo em número de usuários, por exemplo.
Algo que vale ressaltar é a possibilidade de utilizar o File Storage também na versão gratuita para armazenar todo o conteúdo binário (imagens, vídeos, audios, arquivos em geral). Com um acesso mais simples a um servidor de conteúdo estático não precisamos quebrar a cabeça mesclando a configuração do Firebase junto a configuração de um AWS S3, por exemplo.
Segue link dos posts já liberados dessa série:
Twitter Login (Fabric), Firebase Android - Parte 7
Google SignIn API, Firebase Android - Parte 6
Facebook Login, Firebase Android - Parte 5
Remoção de Conta e Dados de Login, Firebase Android - Parte 4
Atualização de Dados, Firebase Android - Parte 3
Eventos de Leitura e Firebase UI Android - Parte 2
Persistência Com Firebase Android - Parte 1
Funcionalidade: Recuperação de Acesso
Agora podemos prosseguir com a adição da funcionalidade de recuperação de acesso.
Nosso primeiro passo é criar uma nova Activity, a ResetActivity:
public class ResetActivity extends AppCompatActivity {
private Toolbar toolbar;
private AutoCompleteTextView email;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reset);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
@Override
protected void onResume() {
super.onResume();
init();
}
private void init(){
toolbar.setTitle( getResources().getString(R.string.reset) );
email = (AutoCompleteTextView) findViewById(R.id.email);
}
public void reset( View view ){
}
}
O método reset() fica vazio por enquanto, vamos seguir atualizando colocando layout e depois voltamos a ele.
Nosso próximo passo é acresentar um novo layout ao /res/layout de nosso projeto, mais precisamente o activity_reset.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="br.com.thiengo.thiengocalopsitafbexample.ResetActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_reset" />
</android.support.design.widget.CoordinatorLayout>
O layout de conteúdo, content_reset.xml (referenciado por activity_reset.xml), acrescentamos ao mesmo folder /res/layout:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="br.com.thiengo.thiengocalopsitafbexample.ResetActivity"
tools:showIn="@layout/activity_update">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<android.support.design.widget.TextInputLayout
android:id="@+id/til_email"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<AutoCompleteTextView
android:id="@+id/email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_email"
android:inputType="textEmailAddress"
android:maxLines="1"
android:singleLine="true" />
</android.support.design.widget.TextInputLayout>
<Button
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:onClick="reset"
android:gravity="center"
android:text="@string/reset_bt_label"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
</ScrollView>
Veja que no button do layout acima temos o atributo android:onClick="reset", logo podemos voltar a ResetActivity para colocar o conteúdo desse método vinculado ao listener de click desse button.
Como variável de instância adicione a FirebaseAuth firebaseAuth, logo depois a inicialize no onCreate() da Activity:
public class ResetActivity extends AppCompatActivity {
private Toolbar toolbar;
private AutoCompleteTextView email;
private FirebaseAuth firebaseAuth;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reset);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
firebaseAuth = FirebaseAuth.getInstance();
}
...
}
Agora podemos colocar somente o código de inicio de recuperação de senha no método reset(), que para facilitar é todo nativo:
...
public void reset( View view ){
firebaseAuth
.sendPasswordResetEmail( email.getText().toString() )
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if( task.isSuccessful() ){
email.setText("");
Toast.makeText(
ResetActivity.this,
"Recuperação de acesso iniciada. Email enviado.",
Toast.LENGTH_SHORT
).show();
}
else{
Toast.makeText(
ResetActivity.this,
"Falhou! Tente novamente",
Toast.LENGTH_SHORT
).show();
}
}
});
}
...
No código acima poderíamos ter colocado um listener para caso o envio falhe, addOnFailureListener(), mas seguindo os exemplos da nova documentação do Firebase, vamos utilizar o resultado da variável task para isso. Apenas precisamos verificar se foi ou não enviado o e-mail com sucesso. De acordo com isso apresentar a mensagem correta.
Ainda temos de colocar a referência da ResetActivity no AndroidManifest.xml e colocar o código necessário em LoginActivity e content_login.xml para acesso a ela.
Abaixo a atualização do AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="br.com.thiengo.thiengocalopsitafbexample">
<uses-permission android:name="android.permission.INTERNET" />
<!-- To auto-complete the email text field in the login form with the user's emails -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<application
android:name=".CustomApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>
<activity android:name="com.facebook.FacebookActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:label="@string/app_name" />
<activity
android:name=".LoginActivity"
android:label="@string/title_activity_login"
android:theme="@style/AppTheme.LoginActionbar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SignUpActivity"
android:label="@string/title_activity_sign_up"
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name=".ResetActivity"
android:theme="@style/AppTheme.NoActionBar" />
<activity android:name=".MainActivity" />
<activity
android:name=".UpdateActivity"
android:label="@string/title_activity_update"
android:theme="@style/AppTheme.NoActionBar"/>
<activity
android:name=".UpdateLoginActivity"
android:label="@string/title_activity_update_login"
android:theme="@style/AppTheme.NoActionBar"/>
<activity
android:name=".UpdatePasswordActivity"
android:label="@string/title_activity_update_password"
android:theme="@style/AppTheme.NoActionBar"/>
<activity
android:name=".RemoveUserActivity"
android:label="@string/title_activity_remove_user"
android:theme="@style/AppTheme.NoActionBar"/>
<meta-data
android:name="io.fabric.ApiKey"
android:value="3dc6b3f7c9b49dc77c730868b0ee3ee4530d9966" />
</application>
</manifest>
Logo depois a atualização de content_login.xml, mais precisamente a adição de um TextView clicável logo abaixo do EditText de senha (@+id/password) desse layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:layout_below="@+id/logo"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".LoginActivity"
tools:showIn="@layout/activity_login">
<!-- Login progress -->
<ProgressBar
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:id="@+id/login_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:visibility="gone" />
...
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_password"
android:imeActionId="@+id/login"
android:imeActionLabel="@string/action_sign_in_short"
android:imeOptions="actionUnspecified"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true" />
</android.support.design.widget.TextInputLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="right"
android:onClick="callReset"
android:text="@string/action_reset_call"
android:textColor="#0000ff" />
...
</RelativeLayout>
Veja que nesse TextView com listener de clique temos a referência ao método callReset() que devemos então adicionar a LoginActivity, logo abaixo do método callSignUp():
public class LoginActivity extends CommonActivity implements GoogleApiClient.OnConnectionFailedListener {
...
public void callSignUp(View view){
Intent intent = new Intent( this, SignUpActivity.class );
startActivity(intent);
}
public void callReset(View view){
Intent intent = new Intent( this, ResetActivity.class );
startActivity(intent);
}
...
}
Com isso nossa funcionalidade de recuperação de senha já está configurada, como na imagem abaixo:
Clicando em "Recuperar acesso" temos:
Realizando o processo (fornecendo email e clicando no botão) recebemos um email similar a:
Clicando no link acessamos uma página simples que permite a redefinição de senha:
Por que similar o conteúdo do email?
Porque podemos fornecer nosso próprio conteúdo acessando o novo dashboard do Firebase em: https://console.firebase.google.com.
Clique no projeto e logo depois, na sessão "Develop", clique em "Auth", em seguida clique na aba "MODELOS DE E-MAIL" e então em "Redefinição de senha".
Clicando no ícone de lápis você poderá informar o conteúdo do email de recuperação de senha, somente não remova a palavra chave %LINK%, pois esse é o link de acesso a página de redefinição de senha:
Lembrando que para acessar o projeto completo, basta acessar o GitHub: https://github.com/viniciusthiengo/nosso-chate
Segue vídeo mostrando o passo a passo do conteúdo acima:
Para saber mais sobre as atualizações do Firebase acesse: The Firebase Blog e a Documentação Firebase
Até o próximo vídeo.
Vlw
Comentários Facebook