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.