trigger onrequest functions json firebase firebase-database database-normalization nosql

json - onrequest - firebase request url



¿Cómo representar una relación bidireccional en un árbol Firebase JSON? (1)

Advertencia:

  • este es un ejercicio para comprender mejor el diseño de la base de datos JSON en Firebase
  • no es necesariamente realista

Tengo una relación de dos maneras entre los usuarios y las llaves de la puerta. Me gustaría entender:

  • cómo representar visualmente esta relación ( puedo imaginarla solo como dos árboles separados )
  • ¿Cómo funcionaría esto en Firebase, los usuarios y las llaves de acceso serían hijos de un nodo padre "myparentnodename"?
  • Si modelizo la base de datos de esta manera, me siento muy ineficiente porque cada vez que consultaba al nodo secundario "usuarios", conseguía recuperar a todos los usuarios. ¿O estoy equivocado? ¿Es posible volver a obtener la coincidencia de datos solo para un usuario específico? Por ejemplo, obtener el usuario donde "usuario = usuario1"? ¿Podemos hacer consultas anidadas? por ejemplo, combinar la condición anterior con alguna condición en las teclas de la puerta para que el objeto JSON devuelto solo sea relevante para las teclas de puerta contenidas en el nodo "usuario1".


Esta es una respuesta muy larga ya que su pregunta era en realidad acerca de 5 preguntas diferentes.

nodo raíz es: myparentnodename

Tus usuarios

users uid_0 name: "William" door_keys: key_0: true key_3: true uid_2 name: "Leonard" door_keys: key_3: true key_5: true

y tus llaves

keys key_0 uid_0: true key_3 uid_0: true uid_2: true key_5 uid_5: true

Con esta estructura, todos los elementos ''apuntan'' el uno al otro.

Si consulta uid_0, puede ver que usan las teclas 0 y 3

Si consulta key_3, puede ver que pertenecen a los usuarios 0 y 2

Tu pregunta fue

cada vez que preguntaba al nodo hijo "usuarios", recuperaba todos los usuarios

Eso es un poco incompleto. Cuando se realiza una consulta, generalmente se busca algo específico. Con Firebase, sin embargo, hay dos formas de recuperar datos: observar un nodo y una consulta.

Si desea recuperar a todos los usuarios en el nodo de usuarios, observaría ese nodo por .Value (o .ChildAdded por 1 a la vez).

ref = myParentNodeName let usersRef = myParentNodeName.childByAppendingPath("users") usersRef.observeEventType(.Value, withBlock: { snapshot in //.Value can return multiple nodes within the snapshot so iterate over them for child in snapshot.children { let name = child.value.objectForKey("name") as! String print(name) //prints each users name } })

tenga en cuenta que lo anterior adjunta un observador al nodo de usuarios por lo que cualquier cambio futuro dentro de ese nodo notificará a la aplicación y volverá a enviar todo el nodo a la aplicación

Si solo desea información de un usuario y no desea seguir buscando cambios

ref = myParentNodeName let usersRef = myParentNodeName.childByAppendingPath("users") let thisUserRef = usersRef.childByAppendingPath("uid_2") thisUserRef.observeSingleEventOfType(.Value, withBlock: { snapshot in let name = child.value.objectForKey("name") as! String print(name) //prints each users name })

Finalmente, para consultar todas las claves que pertenecen a uid_0 (que es un poco redundante en este ejemplo ya que sabemos qué claves tienen desde su nodo). Si las teclas ref también contienen otra información como el nombre de la puerta, el edificio donde estaba la puerta o la ubicación de la puerta, sería más apropiado y requeriría una estructura diferente, así que supongamos que es el caso:

ref = myParentNodeName let keysRef = myParentNodeName.childByAppendingPath("keys") keysRef.queryOrderedByChild("uid_0").queryEqualToValue(true) .observeSingleEventOfType(.Value, withBlock: { snapshot in let doorLocation = child.value.objectForKey("door_location") as! String print(doorLocation) //prints each users name })

tenga en cuenta que este código es Swift ya que la plataforma no se especificó en la pregunta.

La otra pregunta:

¿Podemos hacer consultas anidadas? por ejemplo, combinar la condición anterior con alguna condición en las teclas de la puerta para que el objeto JSON devuelto solo sea relevante para las teclas de puerta contenidas en el nodo "usuario1".

Creo que quieres decir que puedes consultar uid_2, ver qué claves tienen y luego cargar la información de esas claves específicas.

¡Sí! Pero ... (siempre hay un pero)

Firebase es asíncrono, por lo que debe tenerlo en cuenta al anidar consultas, es decir, debe asegurarse de que se devuelven todos los datos antes de obtener más datos. Entonces, por ejemplo, si desea uid_2 datos clave, puede observar SingleEventOfType en el nodo uid_2. Luego tendría sus llaves y podría observar SingleEventOfType en cada tecla.

Técnicamente, esto funcionará, pero con los datos asíncronos volando, podrías terminar con código pisoteando otro código y procesando datos antes de que realmente se haya devuelto.

La mejor opción (por mi ejemplo) es simplemente evitar eso por completo y consultar el nodo de claves para las claves de uid_2.

Como nota al margen, observar un nodo tiene mucho menos sobrecarga que una consulta por lo que si quieres cargar un solo nodo y conoces la ruta, usa observar.