Tengo una lista de suscriptores de correo electrónico y quiero agregar uno nuevo al hacer clic en el botón. Esto debería ser posible para usuarios que no hayan iniciado sesión. Por lo tanto, debe verificarse si esta entrada ya está en la base de datos. Como no quiero exponer la lista completa al usuario que no ha iniciado sesión, ¿cómo verificaría si ya existe una dirección de correo electrónico sin realizar una solicitud GET de búsqueda que tenga derechos para acceder a esa lista con firebase, como todo el código está expuesto en la interfaz? Estoy trabajando con la versión Web9.
import { initializeApp } from "firebase/app"; import { getFirestore, collection, addDoc, getDocs, query, where } from "firebase/firestore"; import { getAuth } from "firebase/auth"; import { getAnalytics } from "firebase/analytics"; const firebaseConfig = { apiKey: "", authDomain: "", projected: "", storageBucket: "", messagingSenderId: "", appId: "", measurementId: "", }; // Initialize Firebase const app = initializeApp(firebaseConfig); const db = getFirestore(); const auth = getAuth(app);Función para agregar el documento:
const addDocument = (dbName, obj) => { return addDoc(collection(db, dbName), obj); };Con las reglas de seguridad de Firestore, puede desglosar una regla de read en get y list como se explica en el documento .
En su caso, asignaría acceso de lectura a todos los get la regla de obtención y denegaría el acceso a la regla de list . De esta manera, los usuarios no autenticados solo pueden obtener un documento específico (identificado con una dirección de correo electrónico específica) y verificar si esta "entrada" dada ya está en la base de datos. No pueden enumerar todas las entradas existentes.
Por supuesto, un usuario puede probar muchas direcciones de correo electrónico diferentes, pero no podrá obtener directamente la lista de todas las entradas existentes en la base de datos con una sola consulta.
Aquí está mi solución de código que espero ayude a alguien. El objetivo ha sido verificar si existe un solo documento y restringir el acceso a la base de datos para verificar la existencia. Encontré solo una opción posible para hacer esto (excluyendo las funciones de la nube). Gracias a la respuesta de @RenaudTarnec. No hay forma de obtener un solo documento con una consulta por valor de campo. La única opción es establecer la identificación del documento en la dirección de correo electrónico especificada (valor que desea consultar).
Código:
Verifique si ya está suscrito, si no, agregue a la base de datos de suscriptores:
const [error, setError] = useState(""); const [message, setMessage] = useState(""); const handleSubmit = async (values: { email: string }) => { const dbName = "newsletterSubscribers"; const docId = values.email; setMessage(""); setError(""); const docRef = doc(db, dbName, docId); const docSnap = await getDoc(docRef); if (docSnap.exists()) { // E-Mail address already subscribed, data: docSnap.data()) setMessage("E-Mail address already subscribed"); } else { // E-Mail is not yet subscribed try { const docRef = await setDoc(doc(db, dbName, docId), { createdAt: serverTimestamp(), }); alert("Thank you for subscribing, you will receive all news and updates to " + values.email); } catch (e) { // Error adding document setError("Failed to subscribe. We're sorry there was an error."); } } };Reglas de seguridad:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /newsletterSubscribers/{subscriberId} { allow get: if true; allow list: if false; allow create: if true; } }}