Android Firebase Authentication — Parte 2

Luis Ferreira
5 min readJul 22, 2016

--

Dando seguimento ao nosso tutorial de como adicionar o firebase ao nosso projeto e utilizar o método de autenticação por e-mail e senha oferecido por ele.

As nossas classes de Login e Cadastro são bem parecidas então vou criar uma classe abstrata para implementar a maior parte das coisas que se repetem para não escrever o mesmo código duas vezes, vamos criar dois métodos abstratos que serão implementados nas nossas classes que vão herdar da nossa classe abstrata. Vamos criar ela com o nome de CommomActivity, segue código da classe:

abstract public class CommonActivity extends AppCompatActivity {

protected AutoCompleteTextView email;
protected EditText password;
protected ProgressBar progressBar;


protected void showSnackbar( String message ){
Snackbar.make(progressBar,
message,
Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}

protected void showToast( String message ){
Toast.makeText(this,
message,
Toast.LENGTH_LONG)
.show();
}

protected void openProgressBar(){
progressBar.setVisibility( View.VISIBLE );
}

protected void closeProgressBar(){
progressBar.setVisibility( View.GONE );
}

abstract protected void inicializarViews();

abstract protected void inicializarUsuario();

public abstract void onConnectionFailed(ConnectionResult connectionResult);
}

Agora vamos enfim codificar nossa CadastroActivity, vá até ela e coloque o seguinte código:

public class CadastroActivity extends CommonActivity implements DatabaseReference.CompletionListener, View.OnClickListener {

private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthStateListener;
private Usuario usuario;
private AutoCompleteTextView name;
private AutoCompleteTextView celular;

private FloatingActionButton FabCadastrar;

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

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

getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle("Cadastro");

mAuth = FirebaseAuth.getInstance();

mAuthStateListener = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();

if (firebaseUser == null || usuario.getId() != null) {
return;
}

usuario.setId(firebaseUser.getUid());
usuario.saveDB(CadastroActivity.this);
}
};

initViews();

FabCadastrar = (FloatingActionButton) findViewById(R.id.fab_enviarDados_Cadastro);
FabCadastrar.setOnClickListener(this);
}

protected void initViews() {
name = (AutoCompleteTextView) findViewById(R.id.edt_Nome_Cadastro);
email = (AutoCompleteTextView) findViewById(R.id.edt_Email_Cadastro);
celular = (AutoCompleteTextView) findViewById(R.id.edt_Celular_Cadastro);
password = (AutoCompleteTextView) findViewById(R.id.edt_Senha_Cadastro);
progressBar = (ProgressBar) findViewById(R.id.sign_up_progress);
}

protected void initUsuario() {
usuario = new Usuario();
usuario.setName(name.getText().toString());
usuario.setEmail(email.getText().toString());
usuario.setCelular(celular.getText().toString());
usuario.setPassword(password.getText().toString());
}

@Override
public void onClick(View v) {
initUsuario();

String NOME = name.getText().toString();
String EMAIL = email.getText().toString();
String CELULAR = celular.getText().toString();
String SENHA = password.getText().toString();

boolean ok = true;

if (NOME.isEmpty()) {
name.setError(getString(R.string.msg_erro_nome));
ok = false;
}

if (EMAIL.isEmpty()) {
email.setError(getString(R.string.msg_erro_email_empty));
ok = false;
}

if (CELULAR.isEmpty()) {
celular.setError(getString(R.string.msg_erro_celular));
ok = false;
}

if (SENHA.isEmpty()) {
password.setError(getString(R.string.msg_erro_senha_empty));
ok = false;
}

if (ok) {
FabCadastrar.setEnabled(false);
progressBar.setFocusable(true);

openProgressBar();
salvarUsuario();
} else {
closeProgressBar();
}
}

@Override
protected void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthStateListener);
}

@Override
protected void onStop() {
super.onStop();
if (mAuthStateListener != null) {
mAuth.removeAuthStateListener(mAuthStateListener);
}
}

private void salvarUsuario() {

mAuth.createUserWithEmailAndPassword(
usuario.getEmail(),
usuario.getPassword()
).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {

if (!task.isSuccessful()) {
closeProgressBar();
}
}
}).addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
showSnackbar(e.getMessage());
FabCadastrar.setEnabled(true);
}
});
}

@Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
mAuth.signOut();

showToast("Conta criada com sucesso!");
closeProgressBar();
finish();
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {

}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
}

return super.onOptionsItemSelected(item);
}
}

Vamos revisar o que foi feito nessa classe. Primeiro declaramos um objeto private FirebaseAuth mAuth que foi usado para obter a instância compartilhada do objeto, mAuth = FirebaseAuth.getInstance(); declaramos um listener FirebaseAuth.AuthStateListener mAuthStateListener, que foi usado para responder as alterações no estado de login do usuário. Após inicializar nossas views e nosso objeto Usuario, no onClick do Float Action Button de cadastro, fiz um breve tratamento para evitar que os campos fiquem vazios. Caso tudo esteja ok, chamamos o método salvarUsuario(); que se encarrega de enviar os dados de login e senha para createUserWithEmailAndPassword, caso as informações de login e senha sejam inseridas com sucesso no firebase, mostramos a mensagem de conta criada com sucesso, caso falhe, o showSnackbar() se encarrega de informar o porquê.

Agora vamos para nossa LoginActivity, insira o seguinte código:

public class LoginActivity extends CommonActivity implements View.OnClickListener {

private FirebaseAuth firebaseAuth;
private FirebaseAuth.AuthStateListener authStateListener;
private Usuario usuario;

private TextView cadastrar;
private Button btnLogin;

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

firebaseAuth = FirebaseAuth.getInstance();
authStateListener = getFirebaseAuthResultHandler();

inicializarViews();

btnLogin = (Button) findViewById(R.id.btn_Login);
btnLogin.setOnClickListener(this);
}

protected void inicializarViews() {
email = (AutoCompleteTextView) findViewById(R.id.edt_Email_Login);
password = (EditText) findViewById(R.id.edt_Senha_Login);
progressBar = (ProgressBar) findViewById(R.id.login_progress);
cadastrar = (TextView) findViewById(R.id.txt_Cadastrar);
}

protected void inicializarUsuario() {
usuario = new Usuario();
usuario.setEmail(email.getText().toString());
usuario.setPassword(password.getText().toString());
}

@Override
public void onClick(View v) {

inicializarUsuario();

int id = v.getId();
if (id == R.id.btn_Login) {

String EMAIL = email.getText().toString();
String SENHA = password.getText().toString();

boolean ok = true;

if (EMAIL.isEmpty()) {
email.setError("E-mail não informado!");

ok = false;
}

if (SENHA.isEmpty()) {
password.setError("Por favor digite uma senha!");

ok = false;
}

if (ok) {
btnLogin.setEnabled(false);
cadastrar.setEnabled(false);
progressBar.setFocusable(true);

openProgressBar();
verifyLogin();
} else {
closeProgressBar();
}
}
}

@Override
protected void onStart() {
super.onStart();
verifyLogged();
}

private void verifyLogged() {

if (firebaseAuth.getCurrentUser() != null) {
chamarMainActivity();
} else {
firebaseAuth.addAuthStateListener(authStateListener);
}
}

@Override
protected void onStop() {
super.onStop();
if (authStateListener != null) {
firebaseAuth.removeAuthStateListener(authStateListener);
}
}

private FirebaseAuth.AuthStateListener getFirebaseAuthResultHandler() {
FirebaseAuth.AuthStateListener callback = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {

FirebaseUser userFirebase = firebaseAuth.getCurrentUser();

if (userFirebase == null) {
return;
}

if (usuario.getId() == null && isNameOk(usuario, userFirebase)) {

usuario.setId(userFirebase.getUid());
usuario.setNameIfNull(userFirebase.getDisplayName());
usuario.setEmailIfNull(userFirebase.getEmail());
usuario.saveDB();
}

chamarMainActivity();
}
};
return (callback);
}

private void verifyLogin() {
firebaseAuth.signInWithEmailAndPassword(
usuario.getEmail(),
usuario.getPassword())
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {

if (!task.isSuccessful()) {
closeProgressBar();

btnLogin.setEnabled(true);
cadastrar.setEnabled(true);

return;
}
}
});
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
showSnackbar(connectionResult.getErrorMessage());
}

private boolean isNameOk(Usuario usuario, FirebaseUser firebaseUser) {
return (usuario.getName() != null || firebaseUser.getDisplayName() != null);
}

private void chamarMainActivity() {
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
}

public void chamarCadastro(View view) {
Intent intent = new Intent(this, CadastroActivity.class);
startActivity(intent);
}
}

Vou explicar apenas o que essa classe tem de diferente da CadastroActivity. Primeiramente no onStart verificamos se o usuário já está logado na aplicação e chamamos diretamente a nossa MainAcitivity. No onClick do botão de entrar chamamos o método verifyLogin(); passamos os dados de endereço de e-mail e a senha desse usuário para signInWithEmailAndPassword: Se o login tiver sucesso, o AuthStateListener executará o retorno de chamada de onAuthStateChanged, senão mostramos uma mensagem ao usuário.

Por fim, na nossa MainActivity:

public class MainActivity extends AppCompatActivity {

private DatabaseReference databaseReference;
private FirebaseAuth firebaseAuth;
private FirebaseAuth.AuthStateListener authStateListener;

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

getSupportActionBar().setTitle("Autenticação Firebase");

authStateListener = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {

if (firebaseAuth.getCurrentUser() == null) {
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
startActivity(intent);
finish();
}
}
};

firebaseAuth = FirebaseAuth.getInstance();
firebaseAuth.addAuthStateListener(authStateListener);
databaseReference = LibraryClass.getFirebase();
databaseReference.getRef();
}


@Override
protected void onDestroy() {
super.onDestroy();

if (authStateListener != null) {
firebaseAuth.removeAuthStateListener(authStateListener);
}
}

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

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

if (id == R.id.action_logout) {
FirebaseAuth.getInstance().signOut();
finish();
}

return super.onOptionsItemSelected(item);
}
}

No activity_main.xml temos apenas um TextView que irá mostrar a mensagem “Parabéns você conseguiu se cadastrar e fazer login com sucesso!”. Criamos também um menu para que o usuário possa fazer logout da nossa aplicação:

<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/acao_sair"
android:orderInCategory="100"
android:title="Sair"
app:showAsAction="never"
/>
</menu>

Então, “isso é tudo pessoal!”. Ficou um pouquinho extenso, mas espero que tenha ajudado quem quer iniciar com o firebase no Android, valeu!

Código completo aqui Android-AutenticacaoFirebase.

Referências: Firebase Authentication, Blog do Thiengo Calopsita.

--

--