Blog para desarrollo de aplicaciones en Android, aprende paso a paso como crear aplicaciones.

Autenticaci贸n Firebase en Android: Email, Google y Facebook

Autenticaci贸n Firebase en Android: Email, Google y Facebook

Hola amigos 馃憢 Bienvenidos a un nuevo tutorial de Universo Android. Hoy aprenderemos a implementar autenticaci贸n con Firebase, usando Email/Contrase帽a, Google Sign-In y Facebook Login para crear un sistema completo de autenticaci贸n en tu app.

Al finalizar este tutorial tendr谩s:

  • Firebase Authentication configurado
  • Login con Email/Contrase帽a
  • Login con Google
  • Login con Facebook
  • Registro de usuarios
  • Recuperaci贸n de contrase帽a
  • Gesti贸n de sesiones

馃煩 1. ¿Qu茅 es Firebase Authentication?

Firebase Authentication proporciona servicios backend para autenticar usuarios de forma f谩cil y segura, soportando m煤ltiples m茅todos de inicio de sesi贸n sin necesidad de c贸digo backend.

馃煩 2. M茅todos Soportados

  • Email/Contrase帽a
  • Google Sign-In
  • Facebook Login
  • Twitter
  • GitHub
  • Phone Number
  • Anonymous

馃煩 3. Crear el Proyecto

Creamos un nuevo proyecto en Android Studio con Empty Activity.

馃煩 4. Configurar Firebase

  1. Ve a Firebase Console
  2. Crea un nuevo proyecto
  3. Agrega tu app Android
  4. Descarga google-services.json
  5. Col贸calo en app/

馃煩 5. Agregar Dependencias

馃搫 build.gradle (Project)

buildscript {
    dependencies {
        classpath 'com.google.gms:google-services:4.4.0'
    }
}

馃搫 build.gradle (Module: app)

plugins {
    id 'com.android.application'
    id 'com.google.gms.google-services'
}

dependencies {
    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.11.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    
    // Firebase BOM
    implementation platform('com.google.firebase:firebase-bom:32.7.0')
    implementation 'com.google.firebase:firebase-auth'
    implementation 'com.google.firebase:firebase-analytics'
    
    // Google Sign-In
    implementation 'com.google.android.gms:play-services-auth:20.7.0'
    
    // Facebook Login
    implementation 'com.facebook.android:facebook-login:16.3.0'
}

馃煩 6. Habilitar M茅todos en Firebase

  1. Firebase Console → Authentication → Sign-in method
  2. Habilita Email/Password
  3. Habilita Google (copia Web client ID)
  4. Habilita Facebook (necesitas App ID y Secret)

馃煩 7. Dise帽o Login

馃搫 activity_login.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true"
    android:background="#FFFFFF">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="24dp"
        android:gravity="center">

        <ImageView
            android:layout_width="120dp"
            android:layout_height="120dp"
            android:src="@android:drawable/ic_dialog_info"
            android:layout_marginTop="40dp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Iniciar Sesi贸n"
            android:textSize="32sp"
            android:textStyle="bold"
            android:textColor="#2196F3"
            android:layout_marginTop="24dp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Bienvenido de nuevo"
            android:textSize="16sp"
            android:textColor="#666666"
            android:layout_marginTop="8dp"
            android:layout_marginBottom="32dp" />

        <!-- Email -->
        <com.google.android.material.textfield.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Email"
            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">

            <com.google.android.material.textfield.TextInputEditText
                android:id="@+id/txtEmail"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:inputType="textEmailAddress" />

        </com.google.android.material.textfield.TextInputLayout>

        <!-- Contrase帽a -->
        <com.google.android.material.textfield.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Contrase帽a"
            android:layout_marginTop="16dp"
            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">

            <com.google.android.material.textfield.TextInputEditText
                android:id="@+id/txtPassword"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:inputType="textPassword" />

        </com.google.android.material.textfield.TextInputLayout>

        <!-- Olvid茅 contrase帽a -->
        <TextView
            android:id="@+id/txtForgotPassword"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="¿Olvidaste tu contrase帽a?"
            android:textColor="#2196F3"
            android:textAlignment="textEnd"
            android:padding="8dp" />

        <!-- Bot贸n Login -->
        <Button
            android:id="@+id/btnLogin"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Iniciar Sesi贸n"
            android:textSize="16sp"
            android:layout_marginTop="16dp"
            android:padding="16dp" />

        <!-- Divider -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:gravity="center"
            android:layout_marginTop="24dp">

            <View
                android:layout_width="0dp"
                android:layout_height="1dp"
                android:layout_weight="1"
                android:background="#CCCCCC" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text=" O contin煤a con "
                android:textColor="#999999"
                android:paddingHorizontal="8dp" />

            <View
                android:layout_width="0dp"
                android:layout_height="1dp"
                android:layout_weight="1"
                android:background="#CCCCCC" />

        </LinearLayout>

        <!-- Social Login Buttons -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_marginTop="24dp">

            <com.google.android.material.button.MaterialButton
                android:id="@+id/btnGoogleLogin"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="Google"
                android:textColor="#FFFFFF"
                app:backgroundTint="#DB4437"
                app:icon="@android:drawable/ic_dialog_info"
                android:layout_marginEnd="8dp"
                style="@style/Widget.MaterialComponents.Button.OutlinedButton" />

            <com.google.android.material.button.MaterialButton
                android:id="@+id/btnFacebookLogin"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="Facebook"
                android:textColor="#FFFFFF"
                app:backgroundTint="#1877F2"
                app:icon="@android:drawable/ic_dialog_info"
                android:layout_marginStart="8dp"
                style="@style/Widget.MaterialComponents.Button.OutlinedButton" />

        </LinearLayout>

        <!-- Registro -->
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_marginTop="24dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="¿No tienes cuenta? "
                android:textColor="#666666" />

            <TextView
                android:id="@+id/txtRegister"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Reg铆strate"
                android:textColor="#2196F3"
                android:textStyle="bold" />

        </LinearLayout>

        <ProgressBar
            android:id="@+id/progressBar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:visibility="gone" />

    </LinearLayout>

</ScrollView>

馃煩 8. LoginActivity

馃搫 LoginActivity.java

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.facebook.AccessToken;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.login.LoginManager;
import com.facebook.login.LoginResult;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.tasks.Task;
import com.google.android.material.textfield.TextInputEditText;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.FacebookAuthProvider;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.GoogleAuthProvider;
import java.util.Arrays;

public class LoginActivity extends AppCompatActivity {

    private FirebaseAuth mAuth;
    private GoogleSignInClient mGoogleSignInClient;
    private CallbackManager mCallbackManager;

    private TextInputEditText txtEmail, txtPassword;
    private Button btnLogin, btnGoogleLogin, btnFacebookLogin;
    private TextView txtForgotPassword, txtRegister;
    private ProgressBar progressBar;

    private ActivityResultLauncher<Intent> googleSignInLauncher;

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

        mAuth = FirebaseAuth.getInstance();

        initializeViews();
        configureGoogleSignIn();
        configureFacebookSignIn();
        setupListeners();

        // Verificar si ya est谩 logueado
        FirebaseUser currentUser = mAuth.getCurrentUser();
        if (currentUser != null) {
            goToMainActivity();
        }
    }

    private void initializeViews() {
        txtEmail = findViewById(R.id.txtEmail);
        txtPassword = findViewById(R.id.txtPassword);
        btnLogin = findViewById(R.id.btnLogin);
        btnGoogleLogin = findViewById(R.id.btnGoogleLogin);
        btnFacebookLogin = findViewById(R.id.btnFacebookLogin);
        txtForgotPassword = findViewById(R.id.txtForgotPassword);
        txtRegister = findViewById(R.id.txtRegister);
        progressBar = findViewById(R.id.progressBar);
    }

    private void configureGoogleSignIn() {
        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestIdToken(getString(R.string.default_web_client_id))
                .requestEmail()
                .build();

        mGoogleSignInClient = GoogleSignIn.getClient(this, gso);

        googleSignInLauncher = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
            result -> {
                if (result.getResultCode() == RESULT_OK) {
                    Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(result.getData());
                    handleGoogleSignInResult(task);
                }
            }
        );
    }

    private void configureFacebookSignIn() {
        mCallbackManager = CallbackManager.Factory.create();

        LoginManager.getInstance().registerCallback(mCallbackManager,
            new FacebookCallback<LoginResult>() {
                @Override
                public void onSuccess(LoginResult loginResult) {
                    handleFacebookAccessToken(loginResult.getAccessToken());
                }

                @Override
                public void onCancel() {
                    Toast.makeText(LoginActivity.this, "Login cancelado", Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onError(FacebookException error) {
                    Toast.makeText(LoginActivity.this, "Error: " + error.getMessage(), Toast.LENGTH_SHORT).show();
                }
            });
    }

    private void setupListeners() {
        btnLogin.setOnClickListener(v -> loginWithEmail());
        btnGoogleLogin.setOnClickListener(v -> signInWithGoogle());
        btnFacebookLogin.setOnClickListener(v -> signInWithFacebook());
        txtForgotPassword.setOnClickListener(v -> resetPassword());
        txtRegister.setOnClickListener(v -> goToRegister());
    }

    private void loginWithEmail() {
        String email = txtEmail.getText().toString().trim();
        String password = txtPassword.getText().toString().trim();

        if (email.isEmpty() || password.isEmpty()) {
            Toast.makeText(this, "Completa todos los campos", Toast.LENGTH_SHORT).show();
            return;
        }

        showProgress(true);

        mAuth.signInWithEmailAndPassword(email, password)
            .addOnCompleteListener(this, task -> {
                showProgress(false);
                
                if (task.isSuccessful()) {
                    FirebaseUser user = mAuth.getCurrentUser();
                    Toast.makeText(this, "Bienvenido " + user.getEmail(), Toast.LENGTH_SHORT).show();
                    goToMainActivity();
                } else {
                    Toast.makeText(this, "Error: " + task.getException().getMessage(), Toast.LENGTH_LONG).show();
                }
            });
    }

    private void signInWithGoogle() {
        Intent signInIntent = mGoogleSignInClient.getSignInIntent();
        googleSignInLauncher.launch(signInIntent);
    }

    private void handleGoogleSignInResult(Task<GoogleSignInAccount> completedTask) {
        try {
            GoogleSignInAccount account = completedTask.getResult(ApiException.class);
            firebaseAuthWithGoogle(account.getIdToken());
        } catch (ApiException e) {
            Toast.makeText(this, "Google sign in failed: " + e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }

    private void firebaseAuthWithGoogle(String idToken) {
        showProgress(true);
        
        AuthCredential credential = GoogleAuthProvider.getCredential(idToken, null);
        mAuth.signInWithCredential(credential)
            .addOnCompleteListener(this, task -> {
                showProgress(false);
                
                if (task.isSuccessful()) {
                    FirebaseUser user = mAuth.getCurrentUser();
                    Toast.makeText(this, "Google login exitoso: " + user.getDisplayName(), Toast.LENGTH_SHORT).show();
                    goToMainActivity();
                } else {
                    Toast.makeText(this, "Error: " + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
                }
            });
    }

    private void signInWithFacebook() {
        LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("email", "public_profile"));
    }

    private void handleFacebookAccessToken(AccessToken token) {
        showProgress(true);
        
        AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken());
        mAuth.signInWithCredential(credential)
            .addOnCompleteListener(this, task -> {
                showProgress(false);
                
                if (task.isSuccessful()) {
                    FirebaseUser user = mAuth.getCurrentUser();
                    Toast.makeText(this, "Facebook login exitoso", Toast.LENGTH_SHORT).show();
                    goToMainActivity();
                } else {
                    Toast.makeText(this, "Error: " + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
                }
            });
    }

    private void resetPassword() {
        String email = txtEmail.getText().toString().trim();
        
        if (email.isEmpty()) {
            Toast.makeText(this, "Ingresa tu email", Toast.LENGTH_SHORT).show();
            return;
        }

        mAuth.sendPasswordResetEmail(email)
            .addOnCompleteListener(task -> {
                if (task.isSuccessful()) {
                    Toast.makeText(this, "Email de recuperaci贸n enviado", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(this, "Error: " + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
                }
            });
    }

    private void goToRegister() {
        startActivity(new Intent(this, RegisterActivity.class));
    }

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

    private void showProgress(boolean show) {
        progressBar.setVisibility(show ? View.VISIBLE : View.GONE);
        btnLogin.setEnabled(!show);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        mCallbackManager.onActivityResult(requestCode, resultCode, data);
    }
}

馃煩 9. RegisterActivity

馃搫 RegisterActivity.java

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.Toast;
import com.google.android.material.textfield.TextInputEditText;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;

public class RegisterActivity extends AppCompatActivity {

    private FirebaseAuth mAuth;
    private TextInputEditText txtEmail, txtPassword, txtConfirmPassword;
    private Button btnRegister;

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

        mAuth = FirebaseAuth.getInstance();

        txtEmail = findViewById(R.id.txtEmail);
        txtPassword = findViewById(R.id.txtPassword);
        txtConfirmPassword = findViewById(R.id.txtConfirmPassword);
        btnRegister = findViewById(R.id.btnRegister);

        btnRegister.setOnClickListener(v -> registerUser());
    }

    private void registerUser() {
        String email = txtEmail.getText().toString().trim();
        String password = txtPassword.getText().toString().trim();
        String confirmPassword = txtConfirmPassword.getText().toString().trim();

        if (email.isEmpty() || password.isEmpty()) {
            Toast.makeText(this, "Completa todos los campos", Toast.LENGTH_SHORT).show();
            return;
        }

        if (password.length() < 6) {
            Toast.makeText(this, "Contrase帽a m铆nimo 6 caracteres", Toast.LENGTH_SHORT).show();
            return;
        }

        if (!password.equals(confirmPassword)) {
            Toast.makeText(this, "Las contrase帽as no coinciden", Toast.LENGTH_SHORT).show();
            return;
        }

        mAuth.createUserWithEmailAndPassword(email, password)
            .addOnCompleteListener(this, task -> {
                if (task.isSuccessful()) {
                    FirebaseUser user = mAuth.getCurrentUser();
                    Toast.makeText(this, "Usuario creado: " + user.getEmail(), Toast.LENGTH_SHORT).show();
                    finish();
                } else {
                    Toast.makeText(this, "Error: " + task.getException().getMessage(), Toast.LENGTH_LONG).show();
                }
            });
    }
}

馃煩 10. MainActivity

馃搫 MainActivity.java

import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;

public class MainActivity extends AppCompatActivity {

    private FirebaseAuth mAuth;
    private TextView txtWelcome, txtUserInfo;
    private Button btnLogout;

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

        mAuth = FirebaseAuth.getInstance();

        txtWelcome = findViewById(R.id.txtWelcome);
        txtUserInfo = findViewById(R.id.txtUserInfo);
        btnLogout = findViewById(R.id.btnLogout);

        displayUserInfo();

        btnLogout.setOnClickListener(v -> logout());
    }

    private void displayUserInfo() {
        FirebaseUser user = mAuth.getCurrentUser();
        
        if (user != null) {
            String info = "Email: " + user.getEmail() + "\n" +
                         "UID: " + user.getUid() + "\n" +
                         "Proveedor: " + user.getProviderId();
            
            txtWelcome.setText("Bienvenido!");
            txtUserInfo.setText(info);
        }
    }

    private void logout() {
        mAuth.signOut();
        startActivity(new Intent(this, LoginActivity.class));
        finish();
    }
}

馃煩 11. Configurar Facebook

馃搫 res/values/strings.xml

<resources>
    <string name="app_name">Firebase Auth</string>
    <string name="facebook_app_id">TU_FACEBOOK_APP_ID</string>
    <string name="fb_login_protocol_scheme">fbTU_FACEBOOK_APP_ID</string>
</resources>

馃搫 AndroidManifest.xml

<application>
    <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:label="@string/app_name" />
        
    <activity android:name="com.facebook.CustomTabActivity"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="@string/fb_login_protocol_scheme" />
        </intent-filter>
    </activity>
</application>

▶️ C贸mo Ejecutar

  1. Configura Firebase Console
  2. Habilita m茅todos de autenticaci贸n
  3. Descarga google-services.json
  4. Configura Facebook App ID
  5. Ejecuta la app

馃И Resultado Final

Sistema completo de autenticaci贸n con Email, Google y Facebook funcionando.

馃摜 Descargar Proyecto

馃憠 

馃檶 Gracias por Visitar mi Blog

✔️ Comp谩rtelo
✔️ D茅jame un comentario
✔️ S铆gueme para m谩s contenido

❓ Preguntas Frecuentes

1. ¿Es gratis Firebase Authentication?
S铆, el plan Spark (gratuito) soporta autenticaci贸n ilimitada.

2. ¿C贸mo obtengo el Facebook App ID?
Crea una app en Facebook Developers Console y copia el App ID.

3. ¿Necesito backend propio?
No, Firebase maneja todo el backend de autenticaci贸n.

4. ¿Puedo combinar m煤ltiples m茅todos?
S铆, puedes vincular m煤ltiples proveedores a una cuenta.

No hay comentarios:

Publicar un comentario