Un tutorial para configurar Firestore como base de datos, ¡una solución muy conveniente para tus problemas de almacenamiento!
Tuve la necesidad de crear un almacenamiento para algunos datos para mi Club de miembros, el lugar donde doy clases de programación.
Quería que mis usuarios pudieran decir manualmente “Completé este curso” haciendo clic en un botón.
Básicamente, quería almacenar un objeto particular para cada usuario.
Configuración de Firebase
Decidí usar Firebase para esto, y en particular la base de datos Firestore que proporciona.
El nivel gratuito es generoso, con hasta 1 GB de datos almacenados y 10 GB de transferencia de red por mes. ¡Supera ampliamente mis estimaciones de lo que necesito!
Abra el sitio web de Firebase en https://firebase.google.com/
Firebase es un producto de Google, por lo que una vez que hayas iniciado sesión en Google, básicamente también habrás iniciado sesión en Firebase.
Crea un nuevo proyecto de Firebase haciendo clic en “Crear un proyecto”
Le di un nombre:
Y eso fue todo:
Haga clic en el ícono “Web” junto a iOS y Android e ingrese el nombre de la aplicación:
Y Firebase inmediatamente me dio las claves de acceso que necesitaba, junto con un código de muestra:
Inmediatamente después de eso, Firebase me pidió que agregara algunas reglas de seguridad para la base de datos.
Puedes elegir 2 cosas por defecto: abierto a todos, o cerrado a todos. Yo empecé abierto a todos, algo que llaman modo de prueba .
¡Eso es todo! Estaba lista para empezar a crear una colección.
¿Qué es una colección? En la terminología de Firestore, podemos crear muchas colecciones diferentes y asignar documentos a cada una de ellas.
Un documento puede entonces contener campos y otras colecciones.
No es muy diferente de otras bases de datos NoSQL, como MongoDB.
Recomiendo mucho ver la lista de reproducción de YouTube sobre el tema, está muy bien hecha.
Así que agregué mi colección, a la que llamé users
.
Quería identificar a cada usuario usando una cadena especial, a la que llamo id
.
El código del frontend
Ahora llegamos a la parte de JavaScript.
En el pie de página, incluí esos 2 archivos, proporcionados por Firebase:
script src="https://www.gstatic.com/firebasejs/7.2.1/firebase-app.js"/scriptscript src="https://www.gstatic.com/firebasejs/7.2.1/firebase-firestore.js"/script
Luego agregué un detector de eventos DOMContentLoaded para asegurarme de ejecutar el código cuando el DOM estuviera listo:
scriptdocument.addEventListener('DOMContentLoaded', event = {})/script
Allí agregué la configuración de Firebase:
const firebaseConfig = { apiKey: "MY-API-KEY", authDomain: "MY-AUTH-DOMAIN", projectId: "MY-PROJECT-ID"}
Pasé este objeto a firebase.initializeApp()
y luego llamé firebase.firestore()
para obtener la referencia al objeto de base de datos:
firebase.initializeApp(firebaseConfig)const db = firebase.firestore()
Ahora, cree un script para completar los ID de usuario de una lista que tenía en mi backend, usando un bucle simple:
const list = [/*...my list...*/]list.forEach(item = { db.collection('users').doc(item).set({})})
…y lo ejecuté una vez para llenar la base de datos. Básicamente, crearé programáticamente un documento para cada usuario .
Esto es muy importante, porque una vez que creé un documento, significó que podía restringir los permisos para solo actualizar esos documentos y no permitir agregar nuevos ni eliminarlos (algo que haremos más adelante).
Bien, ahora tengo una lógica compleja para identificar el ID del usuario y el ID del curso, en lo que no entraré porque no está relacionado con nuestra tarea aquí.
Una vez que reuní eso, pude obtener una referencia al objeto:
const id = /* the user ID */const course = /* the course ID */const docRef = db.doc(`membership/${id}`)
¡Genial! Ahora puedo obtener la referencia del documento desde Firebase:
docRef.get().then(function(doc) { if (doc.exists) { const data = doc.data() document.querySelector('button') .addEventListener('click', () = { data[course] = true docRef.update(data) }) } else { //user does not exist.. }})
En realidad mi lógica era mucho más complicada porque tengo otras partes móviles, ¡pero entiendes la idea!
Inicializo los datos del documento llamando doc.data()
y cuando se hace clic en el botón, que supongo que es el botón para decir “completé el curso”, asociamos el true
valor booleano al identificador del club. Fotos Porno y actrices porno
Más adelante, en cargas posteriores de la página de lista de cursos, puedo inicializar la página y asignar una clase si se ensambla el curso, de esta manera:
for (const [key, value] of Object.entries(data[course])) { const element = document.querySelector('.course-' + course) if (element) { element.classList.add('completed') }}
El problema de los permisos
Comencé Firebase en modo de prueba, ¿recuerdas? Esto hace que la base de datos esté abierta para todos: todos aquellos que tengan las claves de acceso, que son públicas y se publican en el código enviado al frontend.
Así que tuve que hacer una cosa: decidir el nivel de permiso permitido.
Y me topé con un problema bastante importante.
Usando la consola de Firebase, en Reglas, podemos recortar el permiso. Inicialmente, esta era la regla predeterminada:
rules_version = '2';service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write; } }}
Cambié las reglas a read, update
, de modo que solo se pueda actualizar un documento, no crear uno nuevo:
rules_version = '2';service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, update; } }}
Pero no puedo evitar que las personas usen la API de Firebase, ahora disponible gratuitamente en el navegador, para jugar y enumerar todos los demás documentos de la colección, obteniendo acceso a los archivos de otras personas.
Si bien esto no manejó ningún dato confidencial, no fue posible enviar este código.
Trasladar el código del frontend al backend mediante una API personalizada
La cuestión del permiso fue un obstáculo.
Pensé en eliminar todo el código que tenía, pero finalmente descubrí que podía ocultar por completo todo el acceso a la API del navegador y usar un servicio Node.js para ejecutar la API de Firebase.
Este también es un método común para ocultar claves privadas/secretas requeridas por los servicios: esconderlas detrás de un servidor que usted controla.
En lugar de llamar a Firebase desde el navegador, cree un conjunto de puntos finales en mi propio servidor, por ejemplo:
- PUBLICAR para
/course
establecer un curso como completado - POST para
/data
obtener los datos asociados al usuario
y accedo a ellos usando la API Fetch :
const options = { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ id, course, lesson })}const url = BASE_URL + '/lesson'fetch(url, options).catch(err = { console.error('Request failed', err)})
Toda la lógica con los clics de los botones, etc., permanece en el código del lado del cliente, por supuesto, simplemente mueva la lógica de Firebase.
En el lado del servidor Node.js, instalé el firebase
paquete oficial usando npm install firebase
y lo requerí:
const firebase = require('firebase')
Configure un servidor Express para usar CORS e inicialice Firebase:
const firebaseConfig = { apiKey: process.env.APIKEY, authDomain: process.env.AUTHDOMAIN, projectId: process.env.PROJECTID}firebase.initializeApp(firebaseConfig)const db = firebase.firestore()
Entonces, el código es exactamente igual al que se usa en el frontend, excepto que ahora se activa en llamadas de punto final HTTP. Este es el código que devuelve un documento específico de nuestra colección.
const getData = async (id) = { const doc = await db.doc(`membership/${id}`).get() const data = doc.data() if (!data) { console.error('member does not exist') return } return data}app.post('/data', cors(), async (req, res) = { const id = req.body.id if (id) { res.json(await getData(id)) return } res.end()})
Y aquí está la API para establecer un curso como completado:
const setCourseAsCompleted = async (id, course) = { const doc = await db.doc(`membership/${id}`).get() const data = doc.data() if (!data) { console.error('member does not exist') return } if (!data[course]) { data[course] = {} } data[course]['done'] = true db.doc(`membership/${id}`).update(data)}app.post('/course', cors(), (req, res) = { const id = req.body.id const course = req.body.course if (id course) { setCourseAsCompleted(id, course) res.end('ok') return } res.end()})
Básicamente, eso es todo. Se necesita más código para manejar otra lógica, pero la esencia de Firebase es esta que publiqué. Ahora también puedo agregar un usuario para mi servicio del lado del servidor y limitar todos los demás accesos a la API de Firebase y fortalecer la seguridad en ella.
Tal vez te puede interesar:
- Introducción a React
- Agregar evento de clic a los elementos DOM devueltos desde querySelectorAll
- Cómo cambiar el valor de un nodo DOM
- Cómo comprobar si un elemento DOM tiene una clase
Cómo usar Firebase Firestore como base de datos
Configuración de FirebaseEl código del frontendEl problema de los permisosTrasladar el código del frontend al backend mediante una API personalizada
programar
es
https://aprendeprogramando.es/static/images/programar-como-usar-firebase-firestore-como-base-de-datos-2156-0.jpg
2024-10-16
Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente