Estoy tratando de obtener datos de una colección anidada. Cuando creo una cita, estoy guardando el identificador de cita y el identificador de médico en el usuario actual. Cuando los necesito los tomo del usuario. Y ahí está la gran pregunta: estoy creando citas en firestore como esta - citas - [doctorId] (1) - currentDoctorApp - citaId - data part1 | parte2 . Sé que puedo agregar datos como normal - citas - autoId - datos, pero quiero separarlos, para una mejor búsqueda, ¿creo?
(1) - porque creo que si tengo 50 médicos y el usuario actual tiene citas en solo 2 horas, buscaré en estos 2 campos, no en los 50
Esta es la forma en que lo agrego a la colección de citas, pero ¿cómo puedo obtenerlo? Especialmente cuando obtengo más de 1 doctorId. Primero tengo que consultar por ID de documento. espero que no sea muy confuso
try { await setDoc(doc(db, `appointments/${params.doctorId}`, 'currentDoctorApp', generatedId), { doctorId: params.doctorId, userId: currentUser.uid, date: date, hour: hour, status: 'active', address: doctorData.hospitalAddres, hospital: doctorData.hospitalName }); await updateDoc(doc(db, 'users', currentUser.uid), { appointments: arrayUnion({ appointmentId: generatedId, doctorId: params.doctorId, }) }); } catch (error) { console.log(error); }Sugeriría cambiar su estructura de datos de Firestore a esto:
doctors (collection) - documents (auto-id) fields (your-fields): - name - type users (collection) - document (auto-id) - appointments (sub-collection) - documents (auto-id) fields: - address - date - doctorId - hospital - hour - status Si usa la estructura anterior, puede eliminar/eliminar su colección de appointments existente y simplemente consultar la subcolección del usuario para evitar la redundancia. Aquí hay una captura de pantalla de Firestore Structure desde arriba:
users :
appointments (subcolección): 
Para obtener todas las citas de los usuarios, puede consultar de esta manera:
const doctors = collection(db, 'doctors'); const q = query(doctors, where("type", "==", "Psychiatrists")); const querySnapshot = await getDocs(q); querySnapshot.forEach((doc) => { getUsersAppointment(doc.id); }); async function getUsersAppointment(doctorId) { const appointments = query(collectionGroup(db, 'appointments'), where("doctorId", "==", doctorId), where("status", "==", "active")); const querySnapshot = await getDocs(appointments); querySnapshot.forEach((doc) => { console.log(doc.id, ' => ', doc.data()); }); }Al usar collectionGroup , podrá consultar su subcolección, pero primero debe configurar la indexación siguiendo el mensaje en la primera ejecución. El mensaje debería verse así:
[FirebaseError: The query requires an index. You can create it here: https://console.firebase.google.com/v1/r/project/project-id/firestore/indexes?create_composite=ClZwcm9qZWN0cy90aXBoLW1hcmNhbnRob255Yi9kYXRhYmFzZXMvKGRlZmF1bHQpL2NvbGxlY3Rpb25Hcm91cHMvYXBwb2ludG1lbnRzL2luZGV4ZXMvXxACGgwKCGRvY3RvcklkEAEaCgoGc3RhdHVzEAEaDAoIX19uYW1lX18QAQ]Cree el índice y espere a que se habilite. El código anterior daría como resultado:
9smR9t3ZU67CljVIzSbA => { hour: '13:00', address: 'Test Address', doctorId: 'Zx2sWI2KZ3rJbPcUcUKu', hospital: 'MedEx', date: '2022-03-16', status: 'active' }También puede hacerlo a la inversa modificando la estructura de datos anterior si desea que llame a los médicos y también invierta lógicamente el código consultando primero a los usuarios.