Remoção de Conta e Dados de Login, Firebase Android - Parte 4

Receba em primeira mão, e com prioridade, os conteúdos Android exclusivos do Blog. Você receberá um email de confirmação. Somente depois de confirma-lo é que poderei lhe enviar os conteúdos exclusivos.

Email inválido.
Blog /Android /Remoção de Conta e Dados de Login, Firebase Android - Parte 4

Remoção de Conta e Dados de Login, Firebase Android - Parte 4

Vinícius Thiengo
(1874) (3)
Go-ahead
"Infunda sua vida com ação. Não espere que isso aconteça. Faça acontecer. Faça o seu próprio futuro. Faça sua própria esperança. Faça seu próprio amor. E quaisquer que sejam suas crenças, honre seu criador, não esperando passivamente que a graça desça do alto, mas fazendo o que puder para fazer a graça acontecer... você mesmo, agora mesmo, bem aqui na Terra."
Bradley Whitford
Kotlin Android
Capa do livro Desenvolvedor Kotlin Android - Bibliotecas para o dia a dia
TítuloDesenvolvedor Kotlin Android - Bibliotecas para o dia a dia
CategoriasAndroid, Kotlin
AutorVinícius Thiengo
Edição
Capítulos19
Páginas1035
Acessar Livro
Treinamento Oficial
Android: Prototipagem Profissional de Aplicativos
CursoAndroid: Prototipagem Profissional de Aplicativos
CategoriaAndroid
InstrutorVinícius Thiengo
NívelTodos os níveis
Vídeo aulas186
PlataformaUdemy
Acessar Curso
Receitas Android
Capa do livro Receitas Para Desenvolvedores Android
TítuloReceitas Para Desenvolvedores Android
CategoriaDesenvolvimento Android
AutorVinícius Thiengo
Edição
Ano2017
Capítulos20
Páginas936
Acessar Livro
Código Limpo
Capa do livro Refatorando Para Programas Limpos
TítuloRefatorando Para Programas Limpos
CategoriaEngenharia de Software
AutorVinícius Thiengo
Edição
Ano2017
Capítulos46
Páginas599
Acessar Livro
Quer aprender a programar para Android? Acesse abaixo o curso gratuito no Blog.
Conteúdo Exclusivo
Receba em primeira mão, e com prioridade, os conteúdos Android exclusivos do Blog.
Email inválido

Opa, blz?

Nesse post seguimos com a série Firebase no Android, mais precisamente com nossa APP de chat.

Dessa vez vamos abordar as funcionalidades padrões que ainda não colocamos na APP, são elas: atualização de email de login (UpdateLoginActivity), atualização de senha (UpdatePasswordActivity) e remoção de conta de usuário (RemoveUserActivity).

Todas as funcionalidades descritas são simples, porém cada uma tem seus próprios passos para execução, não há um meio de executá-las em uma só chamada a algum método do Firebase, logo foi escolhido manter cada funcionalidade em sua própria Activity.

Antes de iniciar, abaixo seguem os posts anteriores dessa série:

Atualização de Dados, Firebase Android - Parte 3

Eventos de Leitura e Firebase UI Android - Parte 2

Persistência Com Firebase Android - Parte 1

No decorrer do post vamos construindo o conteúdo da APP para que tenhamos as funcionalidades descritas anteriormente. Note que o projeto completo se encontra no GitHub: https://github.com/viniciusthiengo/nosso-chate

Nosso primeiro passo é definir todas as novas activities em nosso AndroidManifest.xml, segue código:

<?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">
<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=".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"/>
</application>
</manifest>

 

Agora vamos para os códigos das novas activities, começando pela activity UpdateLoginActivity:

package br.com.thiengo.thiengocalopsitafbexample;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.AutoCompleteTextView;
import android.widget.EditText;
import android.widget.Toast;
import com.firebase.client.DataSnapshot;
import com.firebase.client.Firebase;
import com.firebase.client.FirebaseError;
import com.firebase.client.ValueEventListener;
import br.com.thiengo.thiengocalopsitafbexample.domain.User;
import br.com.thiengo.thiengocalopsitafbexample.domain.util.LibraryClass;

public class UpdateLoginActivity extends AppCompatActivity implements ValueEventListener {
private Toolbar toolbar;
private User user;
private AutoCompleteTextView newEmail;
private EditText password;

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

toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}

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

private void init(){
toolbar.setTitle( getResources().getString(R.string.update_login) );
newEmail = (AutoCompleteTextView) findViewById(R.id.email);
password = (EditText) findViewById(R.id.password);

user = new User();
user.contextDataDB( this );
}

public void update( View view ){
user.setPassword( password.getText().toString() );
user.generateCryptPassword();

Firebase firebase = LibraryClass.getFirebase();
firebase.changeEmail(
user.getEmail(),
user.getPassword(),
newEmail.getText().toString(),
new Firebase.ResultHandler() {
@Override
public void onSuccess() {
user.setEmail( newEmail.getText().toString() );
user.updateDB();
Toast.makeText(
UpdateLoginActivity.this,
"Email de login atualizado com sucesso",
Toast.LENGTH_SHORT
).show();
}

@Override
public void onError(FirebaseError firebaseError) {
Toast.makeText(
UpdateLoginActivity.this,
firebaseError.getMessage(),
Toast.LENGTH_SHORT
).show();
}
});
}

@Override
public void onDataChange(DataSnapshot dataSnapshot) {
User u = dataSnapshot.getValue( User.class );
newEmail.setText( u.getEmail() );
user.setEmail( u.getEmail() );
}

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

 

Note que o código é bem similar ao código da activity do post anterior, a UpdateActivity. A diferença fica com a view que estamos utilizando, agora é newEmail e não name. A EditText de password, pois devido ser a atualização de um dado crítico é necessário informar a senha também. Além de o método de atualização ser o changeEmail() ao invés de updateChildren().

Note que em onDataChange() estamos acessando o email e o colocando também em user.setEmail(), caminho diferente da lógica utilizada na activity UpdateActivity, onde não colocamos o conteúdo name em user.setName(). Por que isso? Porque no método changeEmail() temos de entrar com: email atual, senha atual, novo email e callback de resposta. Dessa forma o que nos resta é acessar diretamente em newEmail o conteúdo do novo email.

Fique atento ao código dentro de onSuccess() em changeEmail(), pois temos também de atualizar o nodo do usuário atual, digo, o nodo no Firebase, alterar o email para ficar idêntico ao de login. Veja que antes de realizar a chamada a user.updateDB() colocamos o novo email em user e não há necessidade de chamar o método user.retrieveIdSP(), pois na chamada user.contextDataDB() em init() esse id já é recuperado.

Feito isso agora temos os layouts referentes a UpdateLoginActivity. São layouts eles: activity_update_login.xml e content_update_login.xml. Começamos pelo activity_update_login.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.UpdateLoginActivity">

<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_update_login" />

</android.support.design.widget.CoordinatorLayout>

 

Agora prosseguimos com o layout de conteúdo, content_update_login.xml:

<?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.UpdateLoginActivity"
tools:showIn="@layout/activity_update_login">

<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>

<View
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:layout_marginLeft="5dp"
android:id="@+id/v_line"
android:layout_below="@+id/til_email"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="#999"/>

<TextView
android:padding="5dp"
android:background="#ffc"
android:layout_marginRight="4dp"
android:layout_marginLeft="4dp"
android:id="@+id/tv_info"
android:layout_below="@+id/v_line"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/password_info"/>

<android.support.design.widget.TextInputLayout
android:id="@+id/til_password"
android:layout_below="@+id/tv_info"
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/sign_up"
android:imeActionLabel="@string/action_sign_up_short"
android:imeOptions="actionUnspecified"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true" />
</android.support.design.widget.TextInputLayout>

<Button
android:id="@+id/bt_logout"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:onClick="update"
android:gravity="center"
android:text="@string/update_login"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
</ScrollView>

 

Note que já estamos com o ScrollView, na content_update.xml da Activity UpdateActivity também realizamos essa atualização. Por que? Para evitarmos problemas de rolagem de tela quando o device estiver em modo landscape.

Quando chegar a hora de rodar a APP essas definições de layout terão um resultado similar a imagem abaixo:

Nosso próximo passo é a activity UpdatePasswordActivity, segue código:

package br.com.thiengo.thiengocalopsitafbexample;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import com.firebase.client.DataSnapshot;
import com.firebase.client.Firebase;
import com.firebase.client.FirebaseError;
import com.firebase.client.ValueEventListener;
import br.com.thiengo.thiengocalopsitafbexample.domain.User;
import br.com.thiengo.thiengocalopsitafbexample.domain.util.LibraryClass;

public class UpdatePasswordActivity extends AppCompatActivity implements ValueEventListener {
private Toolbar toolbar;
private User user;
private EditText newPassword;
private EditText password;

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

toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}

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

private void init(){
toolbar.setTitle( getResources().getString(R.string.update_password) );
newPassword = (EditText) findViewById(R.id.new_password);
password = (EditText) findViewById(R.id.password);
user = new User();
user.contextDataDB( this );
}

public void update( View view ){
user.setNewPassword( newPassword.getText().toString() );
user.generateCryptNewPassword();
user.setPassword( password.getText().toString() );
user.generateCryptPassword();

Firebase firebase = LibraryClass.getFirebase();
firebase.changePassword(
user.getEmail(),
user.getPassword(),
user.getNewPassword(),
new Firebase.ResultHandler() {
@Override
public void onSuccess() {
Toast.makeText(
UpdatePasswordActivity.this,
"Senha atualizada com sucesso",
Toast.LENGTH_SHORT
).show();
}

@Override
public void onError(FirebaseError firebaseError) {
Toast.makeText(
UpdatePasswordActivity.this,
firebaseError.getMessage(),
Toast.LENGTH_SHORT
).show();
}
}
);
}

@Override
public void onDataChange(DataSnapshot dataSnapshot) {
User u = dataSnapshot.getValue( User.class );
user.setEmail( u.getEmail() );
}

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

 

Código muito similar ao anterior, tendo agora o acesso ao EditText newPassword ao invés do AutoCompleteTextView newEmail de UpdateloginActivity. Note que ainda em onDataChange() estamos obtendo o email atual de cadastrado, pois o método changePassword() precisa que o email de login também seja fornecido.

O resultado, quando positivo, aqui é bem mais simples, pois não precisamos atualizar nada na base Firebase utilizando o método updateDB() de user.

A classe User agora tem os mesmos métodos de password replicados para newPassword:

@JsonIgnoreProperties({"id", "password", "newPassword"})
public class User {
...
private String newPassword;
...
public String getNewPassword() {
return newPassword;
}

public void setNewPassword(String newPassword) {
this.newPassword = newPassword;
}

public void generateCryptNewPassword() {
newPassword = CryptWithMD5.cryptWithMD5(newPassword);
}
...
}

 

Note que em @JsonIgnoreProperties() adicionamos newPassword para que o parse Firebase não gere uma Exception.

Agora seguimos com os layouts de UpdatePasswordActivity, activity_update_password.xml e content_update_password.xml. Começando pelo activity_update_password.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.UpdatePasswordActivity">

<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_update_password" />

</android.support.design.widget.CoordinatorLayout>

 

E então o código xml de content_update_password.xml:

<?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.UpdatePasswordActivity"
tools:showIn="@layout/activity_update_password">

<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_new_password"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/new_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_new_password"
android:imeActionId="@+id/sign_up"
android:imeActionLabel="@string/action_sign_up_short"
android:imeOptions="actionUnspecified"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true" />
</android.support.design.widget.TextInputLayout>

<View
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:layout_marginLeft="5dp"
android:id="@+id/v_line"
android:layout_below="@+id/til_new_password"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="#999"/>

<TextView
android:padding="5dp"
android:background="#ffc"
android:layout_marginRight="4dp"
android:layout_marginLeft="4dp"
android:id="@+id/tv_info"
android:layout_below="@+id/v_line"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/password_info"/>

<android.support.design.widget.TextInputLayout
android:id="@+id/til_password"
android:layout_below="@+id/tv_info"
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/sign_up"
android:imeActionLabel="@string/action_sign_up_short"
android:imeOptions="actionUnspecified"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true" />
</android.support.design.widget.TextInputLayout>

<Button
android:id="@+id/bt_logout"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:onClick="update"
android:gravity="center"
android:text="@string/update_password"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
</ScrollView>

 

No momento de rodar a APP essas definições de layout para UpdatePasswordActivity terão um resultado similar a:

 

Agora podemos seguir com o código de RemoveUserActivity:

package br.com.thiengo.thiengocalopsitafbexample;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import com.firebase.client.DataSnapshot;
import com.firebase.client.Firebase;
import com.firebase.client.FirebaseError;
import com.firebase.client.ValueEventListener;
import br.com.thiengo.thiengocalopsitafbexample.domain.User;
import br.com.thiengo.thiengocalopsitafbexample.domain.util.LibraryClass;

public class RemoveUserActivity extends AppCompatActivity implements ValueEventListener {

private Toolbar toolbar;
private User user;
private EditText password;

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

toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}

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

private void init(){
toolbar.setTitle( getResources().getString(R.string.remove_user) );
password = (EditText) findViewById(R.id.password);

user = new User();
user.contextDataDB( this );
}

public void update( View view ){
user.setPassword( password.getText().toString() );
user.generateCryptPassword();

Firebase firebase = LibraryClass.getFirebase();
firebase.removeUser(
user.getEmail(),
user.getPassword(),
new Firebase.ResultHandler() {
@Override
public void onSuccess() {
user.retrieveIdSP( RemoveUserActivity.this );
user.removeDB();
Toast.makeText(
RemoveUserActivity.this,
"Conta removida com sucesso",
Toast.LENGTH_SHORT
).show();
finish();
}

@Override
public void onError(FirebaseError firebaseError) {
Toast.makeText(
RemoveUserActivity.this,
firebaseError.getMessage(),
Toast.LENGTH_SHORT
).show();
}
}
);
}

@Override
public void onDataChange(DataSnapshot dataSnapshot) {
User u = dataSnapshot.getValue( User.class );
user.setEmail( u.getEmail() );
}

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

 

Note que ainda mantemos o código user.setEmail( u.getEmail() ) em onDataChange(), pois o método removeUser() precisa dos dados de login.

A chamada a user.removeDB() é necessária, pois o que o método removeUser() vai fazer é apenas remover os dados de autenticação do usuário, na base Firebase ainda vai permanecer os dados dele, logo o método removeDB() remove o restante. Abaixo o código de removeDB() em User:

public class User {
...
public void removeDB(){
Firebase firebase = LibraryClass.getFirebase().child("users").child( getId() );
firebase.setValue(null);
}
...
}

 

Agora podemos seguir com os layouts de RemoveUserActivity, activity_remove_user.xml e content_remove_user.xml. Começando por activity_remove_user.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.RemoveUserActivity">

<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_remove_user" />

</android.support.design.widget.CoordinatorLayout>

 

E então content_remove_user.xml:

<?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.RemoveUserActivity"
tools:showIn="@layout/activity_remove_user">

<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">

<TextView
android:padding="5dp"
android:background="#ffc"
android:layout_marginRight="4dp"
android:layout_marginLeft="4dp"
android:id="@+id/tv_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/password_info"/>

<android.support.design.widget.TextInputLayout
android:id="@+id/til_password"
android:layout_below="@+id/tv_info"
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/sign_up"
android:imeActionLabel="@string/action_sign_up_short"
android:imeOptions="actionUnspecified"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true" />
</android.support.design.widget.TextInputLayout>

<Button
android:id="@+id/bt_logout"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:onClick="update"
android:gravity="center"
android:text="@string/remove_user"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
</ScrollView>

 

Na execução da APP teremos como resultado das definições de layout de RemoveUserLayout algo similar a imagem abaixo:

Os próximos passos envolvem a MainActivity e o arquivo res/var/strings.xml. Começando pelo strings.xml, adicione as seguintes tags:

<resources>
...
<string name="prompt_new_password">Nova senha</string>
<string name="update_profile">Atualizar profile</string>
<string name="update_login">Atualizar login</string>
<string name="update_password">Atualizar senha</string>
<string name="remove_user">Remover conta</string>
<string name="title_activity_update_login">UpdateLoginActivity</string>
<string name="title_activity_update_password">UpdatePasswordActivity</string>
<string name="title_activity_remove_user">RemoveUserActivity</string>
<string name="password_info">Para prosseguir com a atualização informe abaixo sua senha.</string>
</resources>

 

Agora em res/menu/menu.xml em MainActivity temos o seguinte xml:

<?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/update_profile"
app:showAsAction="never" />

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

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

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

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

 

Com isso podemos iniciar as atualizações na MainActivity, começando pelo método onOptionsItemSelected() onde teremos alguns outros condicionais para nossas novas activities:

public class MainActivity extends AppCompatActivity {
...

@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_update_login){
startActivity(new Intent(this, UpdateLoginActivity.class));
}
else if(id == R.id.action_update_password){
startActivity(new Intent(this, UpdatePasswordActivity.class));
}
else if(id == R.id.action_remove_user){
startActivity(new Intent(this, RemoveUserActivity.class));
}
else if(id == R.id.action_logout){
firebase.unauth();

Intent intent = new Intent(this, LoginActivity.class);
startActivity(intent);
finish();
}
return super.onOptionsItemSelected(item);
}
}

 

Com isso temos o seguinte menu em MainActivity:

Note que em RemoveUserActivity, mais precisamente no método removeUser(), o único finish() não é o suficiente para voltar o usuário para a tela de login caso ele remova a conta, ainda precisamos saber no código se ele permanece ou não conectado para que seja possível envia-lo ou não a tela de login (LoginActivity).

O que devemos fazer é adicionar uma instancia de uma classe que implemente a interface AuthStateListener, logo podemos utilizar Firebase.AuthStateListener. Segue código da MainActivity atualizado:

public class MainActivity extends AppCompatActivity {
...
private Firebase.AuthStateListener authStateListener;

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

authStateListener = new Firebase.AuthStateListener() {
@Override
public void onAuthStateChanged(AuthData authData) {
if( authData == null ){
Intent intent = new Intent( MainActivity.this, LoginActivity.class );
startActivity( intent );
finish();
}
}
};

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

...

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

 

Se em onAuthStateChanged() o valor de authData for igual a null podemos seguramente enviar o usuário para a tela de login, pois ele não mais está conectado.

Com isso terminamos a atualização para termos as funcionalidades de: atualização de email de login, de password e remoção de conta.

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

O vídeo abaixo tem a implementação completa do código acima, passo a passo.

Fonte:

Email & Password Authentication

Vlw

 

Receba em primeira mão, e com prioridade, os conteúdos Android exclusivos do Blog.
Email inválido

Relacionado

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
Refatoração Para PadrõesRefatoração Para PadrõesLivros
Refatoração de Código: Formar Template MethodRefatoração de Código: Formar Template MethodAndroid

Compartilhar

Comentários Facebook (3)

Comentários Blog

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...