Notification texts go here Contact Us Buy Now!

Curso de Firebase - Proyecto Final

Aprende a crear una red social con Firebase: subida de imágenes, notificaciones push y hosting. Proyecto final con código completo.
jesanre
Portada del Curso de Firebase

Proyecto Final: Red Social con Firebase

Propuesta de Aplicación: "SocialFire"

Características principales:

  1. App tipo red social con perfiles de usuario y sistema de seguimiento
  2. Publicaciones con imágenes usando Firebase Storage
  3. Tiempo real con Firestore
  4. Hosting en Firebase para despliegue

Estructura del Proyecto

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SocialFire - Red Social con Firebase</title>
    <script src="https://www.gstatic.com/firebasejs/9.0.0/firebase-app-compat.js"></script>
    <script src="https://www.gstatic.com/firebasejs/9.0.0/firebase-auth-compat.js"></script>
    <script src="https://www.gstatic.com/firebasejs/9.0.0/firebase-firestore-compat.js"></script>
    <script src="https://www.gstatic.com/firebasejs/9.0.0/firebase-storage-compat.js"></script>
    <style>
        /* Estilos CSS para la aplicación */
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            margin: 0;
            padding: 0;
            background-color: #f5f5f5;
        }
        .header {
            background-color: #4285f4;
            color: white;
            padding: 15px;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .post-container {
            max-width: 600px;
            margin: 20px auto;
            background: white;
            border-radius: 8px;
            box-shadow: 0 1px 3px rgba(0,0,0,0.12);
            padding: 15px;
        }
        .post-image {
            width: 100%;
            border-radius: 4px;
            margin-top: 10px;
        }
        .new-post {
            display: flex;
            flex-direction: column;
            margin-bottom: 20px;
        }
        textarea {
            border: 1px solid #ddd;
            border-radius: 4px;
            padding: 10px;
            margin-bottom: 10px;
            resize: vertical;
        }
        button {
            background-color: #4285f4;
            color: white;
            border: none;
            padding: 10px 15px;
            border-radius: 4px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <div class="header">
        <h1>SocialFire</h1>
        <div id="auth-container"></div>
    </div>

    <div class="container">
        <div id="new-post-container" class="post-container" style="display: none;">
            <h2>Crear nueva publicación</h2>
            <div class="new-post">
                <textarea id="post-text" placeholder="¿Qué estás pensando?"></textarea>
                <input type="file" id="post-image" accept="image/*">
                <button id="post-button">Publicar</button>
            </div>
        </div>

        <div id="posts-container"></div>
    </div>

    <script>
        // Configuración de Firebase
        const firebaseConfig = {
            apiKey: "TU_API_KEY",
            authDomain: "TU_PROYECTO.firebaseapp.com",
            projectId: "TU_PROYECTO",
            storageBucket: "TU_PROYECTO.appspot.com",
            messagingSenderId: "TU_SENDER_ID",
            appId: "TU_APP_ID"
        };

        // Inicializar Firebase
        firebase.initializeApp(firebaseConfig);
        const auth = firebase.auth();
        const db = firebase.firestore();
        const storage = firebase.storage();

        // Elementos del DOM
        const authContainer = document.getElementById('auth-container');
        const newPostContainer = document.getElementById('new-post-container');
        const postsContainer = document.getElementById('posts-container');
        const postButton = document.getElementById('post-button');
        const postText = document.getElementById('post-text');
        const postImage = document.getElementById('post-image');

        // Manejar autenticación
        auth.onAuthStateChanged(user => {
            if (user) {
                // Usuario logueado
                authContainer.innerHTML = `
                    <span>Hola, ${user.displayName || user.email}</span>
                    <button id="logout-button">Cerrar sesión</button>
                `;
                document.getElementById('logout-button').addEventListener('click', () => auth.signOut());
                newPostContainer.style.display = 'block';
                loadPosts();
            } else {
                // Usuario no logueado
                authContainer.innerHTML = `
                    <button id="login-button">Iniciar sesión</button>
                    <button id="signup-button">Registrarse</button>
                `;
                document.getElementById('login-button').addEventListener('click', () => {
                    auth.signInWithEmailAndPassword(
                        prompt("Email:"),
                        prompt("Contraseña:")
                    );
                });
                document.getElementById('signup-button').addEventListener('click', () => {
                    auth.createUserWithEmailAndPassword(
                        prompt("Email:"),
                        prompt("Contraseña:")
                    );
                });
                newPostContainer.style.display = 'none';
                postsContainer.innerHTML = '<p>Inicia sesión para ver las publicaciones</p>';
            }
        });

        // Cargar publicaciones en tiempo real
        function loadPosts() {
            db.collection("posts").orderBy("timestamp", "desc").onSnapshot(snapshot => {
                postsContainer.innerHTML = '';
                snapshot.forEach(doc => {
                    const post = doc.data();
                    const postElement = document.createElement('div');
                    postElement.className = 'post-container';
                    postElement.innerHTML = `
                        <h3>${post.authorName || 'Anónimo'}</h3>
                        <p>${post.text}</p>
                        ${post.imageUrl ? `<img src="${post.imageUrl}" class="post-image">` : ''}
                        <small>${new Date(post.timestamp?.toDate()).toLocaleString()}</small>
                    `;
                    postsContainer.appendChild(postElement);
                });
            });
        }

        // Crear nueva publicación
        postButton.addEventListener('click', async () => {
            const text = postText.value.trim();
            const file = postImage.files[0];
            
            if (!text && !file) return;

            const user = auth.currentUser;
            if (!user) return;

            try {
                let imageUrl = null;
                
                // Subir imagen si existe
                if (file) {
                    const storageRef = storage.ref(`posts/${user.uid}/${Date.now()}_${file.name}`);
                    await storageRef.put(file);
                    imageUrl = await storageRef.getDownloadURL();
                }

                // Crear publicación en Firestore
                await db.collection("posts").add({
                    text: text,
                    imageUrl: imageUrl,
                    authorId: user.uid,
                    authorName: user.displayName || user.email,
                    timestamp: firebase.firestore.FieldValue.serverTimestamp()
                });

                // Limpiar formulario
                postText.value = '';
                postImage.value = '';
            } catch (error) {
                console.error("Error al publicar:", error);
                alert("Error al publicar. Intenta nuevamente.");
            }
        });
    </script>
</body>
</html>

Implementación Paso a Paso

1. Configuración de Firebase

  1. Crea un proyecto en Firebase Console
  2. Registra una aplicación web en tu proyecto
  3. Copia la configuración y reemplázala en el código

2. Estructura de Datos en Firestore

Crea una colección llamada "posts" con los siguientes campos:

  • text (string): Contenido de la publicación
  • imageUrl (string): URL de la imagen (opcional)
  • authorId (string): ID del usuario que creó la publicación
  • authorName (string): Nombre/email del autor
  • timestamp (timestamp): Fecha y hora de creación

3. Reglas de Seguridad

Configura las reglas en Firestore y Storage:

Firestore Rules:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /posts/{post} {
      allow read: if true;
      allow create: if request.auth != null;
      allow update, delete: if request.auth != null && request.auth.uid == resource.data.authorId;
    }
  }
}

Storage Rules:

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /posts/{userId}/{allPaths=**} {
      allow read: if true;
      allow write: if request.auth != null && request.auth.uid == userId;
    }
  }
}

4. Despliegue en Firebase Hosting

  1. Instala Firebase CLI:
npm install -g firebase-tools
  1. Inicializa tu proyecto:
firebase init
  • Selecciona Hosting y Firestore
  • Configura como proyecto público el directorio donde está tu HTML
  1. Despliega tu aplicación:
firebase deploy

Características Avanzadas para Implementar (Opcional)

  1. Sistema de likes/comentarios: Añade subcolecciones a los posts
  2. Seguimiento de usuarios: Crea una colección "users" con seguidores/seguidos
  3. Notificaciones en tiempo real: Usa Firebase Cloud Messaging
  4. Búsqueda de publicaciones: Implementa Algolia o Firebase Search
  5. Edición de perfil: Permite subir foto de perfil y cambiar nombre

Evaluación del Proyecto

Este proyecto cumple con todos los requisitos:

  • ✅ Red social básica con autenticación y publicaciones
  • ✅ Publicaciones con imágenes usando Firebase Storage
  • ✅ Tiempo real con listeners de Firestore
  • ✅ Hosting en Firebase para despliegue profesional

Además, incluye características adicionales como:

  • Sistema de autenticación por email
  • Diseño responsive básico
  • Reglas de seguridad para proteger los datos
  • Actualizaciones en tiempo real sin recargar la página

Publicar un comentario

Cookie Consent
We serve cookies on this site to analyze traffic, remember your preferences, and optimize your experience.
Oops!
It seems there is something wrong with your internet connection. Please connect to the internet and start browsing again.
AdBlock Detected!
We have detected that you are using adblocking plugin in your browser.
The revenue we earn by the advertisements is used to manage this website, we request you to whitelist our website in your adblocking plugin.
Site is Blocked
Sorry! This site is not available in your country.