TechLead
Lección 2 de 8
6 min de lectura
Firebase

Autenticación de Firebase

Implementa autenticación de usuarios con email/contraseña, logins sociales y más

¿Qué es Firebase Authentication?

Firebase Authentication ofrece servicios backend, SDKs fáciles de usar y bibliotecas UI listas para autenticar usuarios en tu app. Soporta autenticación con contraseñas, números de teléfono, proveedores federados populares como Google, Facebook, Twitter y más.

Firebase Auth se integra estrechamente con otros servicios de Firebase y aprovecha estándares como OAuth 2.0 y OpenID Connect, lo que facilita su integración con un backend personalizado.

🔐 Métodos de autenticación

  • 📧 Email/Contraseña: Registro e inicio de sesión tradicional con email.
  • 📱 Número de teléfono: Verificación por SMS.
  • 🔗 Proveedores sociales: Google, Facebook, Twitter, GitHub, Apple, Microsoft.
  • 🔑 Anónima: Crear cuentas anónimas temporales.
  • 🎫 Autenticación personalizada: Integración con tu propio sistema.

Configurar la autenticación

Primero, habilita los métodos en la consola de Firebase:

  1. Ve a Firebase Console → Authentication
  2. Haz clic en "Get started" si aún no lo hiciste
  3. Ve a la pestaña "Sign-in method"
  4. Habilita los proveedores que quieres usar
// Import auth functions
import {
  getAuth,
  createUserWithEmailAndPassword,
  signInWithEmailAndPassword,
  signOut,
  onAuthStateChanged,
  GoogleAuthProvider,
  signInWithPopup
} from 'firebase/auth';

// Get the auth instance
const auth = getAuth();

Autenticación con email/contraseña

El método de autenticación más común:

Crear un usuario nuevo

async function signUp(email, password) {
  try {
    const userCredential = await createUserWithEmailAndPassword(
      auth,
      email,
      password
    );
    const user = userCredential.user;
    console.log('User created:', user.uid);
    return user;
  } catch (error) {
    console.error('Error signing up:', error.code, error.message);
    throw error;
  }
}

// Usage
await signUp('user@example.com', 'securePassword123');

Iniciar sesión de usuario existente

async function signIn(email, password) {
  try {
    const userCredential = await signInWithEmailAndPassword(
      auth,
      email,
      password
    );
    const user = userCredential.user;
    console.log('Signed in:', user.email);
    return user;
  } catch (error) {
    switch (error.code) {
      case 'auth/user-not-found':
        console.error('No user found with this email');
        break;
      case 'auth/wrong-password':
        console.error('Invalid password');
        break;
      default:
        console.error('Sign in error:', error.message);
    }
    throw error;
  }
}

Cerrar sesión

async function logOut() {
  try {
    await signOut(auth);
    console.log('User signed out');
  } catch (error) {
    console.error('Error signing out:', error);
  }
}

Inicio de sesión con Google

Agrega autenticación con Google con pocas líneas de código:

import { GoogleAuthProvider, signInWithPopup } from 'firebase/auth';

const googleProvider = new GoogleAuthProvider();

// Optional: Add scopes for additional permissions
googleProvider.addScope('https://www.googleapis.com/auth/contacts.readonly');

async function signInWithGoogle() {
  try {
    const result = await signInWithPopup(auth, googleProvider);

    // This gives you a Google Access Token
    const credential = GoogleAuthProvider.credentialFromResult(result);
    const token = credential.accessToken;

    // The signed-in user info
    const user = result.user;
    console.log('Google user:', user.displayName, user.email);

    return user;
  } catch (error) {
    console.error('Google sign-in error:', error);
    throw error;
  }
}

Escuchar el estado de autenticación

Detecta cuando los usuarios inician o cierran sesión:

import { onAuthStateChanged } from 'firebase/auth';

// Set up auth state listener
const unsubscribe = onAuthStateChanged(auth, (user) => {
  if (user) {
    // User is signed in
    console.log('User is logged in:', user.uid);
    console.log('Email:', user.email);
    console.log('Display name:', user.displayName);
    console.log('Photo URL:', user.photoURL);
    console.log('Email verified:', user.emailVerified);
  } else {
    // User is signed out
    console.log('User is logged out');
  }
});

// Later, unsubscribe when component unmounts
unsubscribe();

Hook de React para autenticación

Crea un hook personalizado para manejar el estado en React:

// hooks/useAuth.js
import { useState, useEffect } from 'react';
import { auth } from '../lib/firebase';
import {
  onAuthStateChanged,
  signInWithEmailAndPassword,
  createUserWithEmailAndPassword,
  signOut
} from 'firebase/auth';

export function useAuth() {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (user) => {
      setUser(user);
      setLoading(false);
    });

    return unsubscribe;
  }, []);

  const login = (email, password) => {
    return signInWithEmailAndPassword(auth, email, password);
  };

  const register = (email, password) => {
    return createUserWithEmailAndPassword(auth, email, password);
  };

  const logout = () => {
    return signOut(auth);
  };

  return { user, loading, login, register, logout };
}
// Usage in a component
function Profile() {
  const { user, loading, logout } = useAuth();

  if (loading) return <div>Loading...</div>;

  if (!user) return <div>Please sign in</div>;

  return (
    <div>
      <p>Welcome, {user.email}!</p>
      <button onClick={logout}>Sign Out</button>
    </div>
  );
}

Restablecer contraseña

Permite que los usuarios restablezcan su contraseña por email:

import { sendPasswordResetEmail } from 'firebase/auth';

async function resetPassword(email) {
  try {
    await sendPasswordResetEmail(auth, email);
    console.log('Password reset email sent');
  } catch (error) {
    console.error('Error sending reset email:', error);
    throw error;
  }
}

Verificación de correo

Envía emails de verificación para confirmar direcciones:

import { sendEmailVerification } from 'firebase/auth';

async function verifyEmail() {
  const user = auth.currentUser;
  if (user) {
    try {
      await sendEmailVerification(user);
      console.log('Verification email sent');
    } catch (error) {
      console.error('Error sending verification:', error);
    }
  }
}

// Check if email is verified
function isEmailVerified() {
  const user = auth.currentUser;
  return user?.emailVerified ?? false;
}

Actualizar perfil de usuario

Actualiza nombre visible y foto de perfil:

import { updateProfile, updateEmail } from 'firebase/auth';

async function updateUserProfile(displayName, photoURL) {
  const user = auth.currentUser;
  if (user) {
    try {
      await updateProfile(user, {
        displayName: displayName,
        photoURL: photoURL
      });
      console.log('Profile updated');
    } catch (error) {
      console.error('Error updating profile:', error);
    }
  }
}

async function updateUserEmail(newEmail) {
  const user = auth.currentUser;
  if (user) {
    try {
      await updateEmail(user, newEmail);
      console.log('Email updated');
    } catch (error) {
      console.error('Error updating email:', error);
    }
  }
}

Rutas protegidas (ejemplo en Next.js)

Crea rutas protegidas que requieren autenticación:

// components/ProtectedRoute.js
'use client';
import { useAuth } from '../hooks/useAuth';
import { useRouter } from 'next/navigation';
import { useEffect } from 'react';

export default function ProtectedRoute({ children }) {
  const { user, loading } = useAuth();
  const router = useRouter();

  useEffect(() => {
    if (!loading && !user) {
      router.push('/login');
    }
  }, [user, loading, router]);

  if (loading) {
    return <div>Loading...</div>;
  }

  if (!user) {
    return null;
  }

  return children;
}

// Usage
export default function DashboardPage() {
  return (
    <ProtectedRoute>
      <Dashboard />
    </ProtectedRoute>
  );
}

💡 Puntos clave

  • • Firebase Auth soporta email/contraseña, logins sociales y más
  • • Usa onAuthStateChanged para rastrear el estado de autenticación
  • • Crea hooks personalizados para una integración limpia en React
  • • Maneja errores con códigos específicos
  • • Implementa rutas protegidas para asegurar páginas
  • • Verifica siempre los correos en apps sensibles

📚 Más recursos

Continuar Aprendiendo