Proyecto Final: Red Social con Firebase
Propuesta de Aplicación: "SocialFire"
Características principales:
- App tipo red social con perfiles de usuario y sistema de seguimiento
- Publicaciones con imágenes usando Firebase Storage
- Tiempo real con Firestore
- 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
- Crea un proyecto en Firebase Console
- Registra una aplicación web en tu proyecto
- 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ónimageUrl
(string): URL de la imagen (opcional)authorId
(string): ID del usuario que creó la publicaciónauthorName
(string): Nombre/email del autortimestamp
(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
- Instala Firebase CLI:
npm install -g firebase-tools
- Inicializa tu proyecto:
firebase init
- Selecciona Hosting y Firestore
- Configura como proyecto público el directorio donde está tu HTML
- Despliega tu aplicación:
firebase deploy
Características Avanzadas para Implementar (Opcional)
- Sistema de likes/comentarios: Añade subcolecciones a los posts
- Seguimiento de usuarios: Crea una colección "users" con seguidores/seguidos
- Notificaciones en tiempo real: Usa Firebase Cloud Messaging
- Búsqueda de publicaciones: Implementa Algolia o Firebase Search
- 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
0 Comentarios