7

Attenzione:Come rappresentare una relazione a due vie in un albero JSON Firebase?

  • questo è un esercizio per capire meglio la progettazione di database JSON in Firebase
  • non è necessariamente realistico

ho avuto una relazione in due modi tra gli utenti e le chiavi della porta. Vorrei capire:

  • come rappresentare questo rapporto visivo (posso immaginare solo come due alberi separati)
  • come questo possa lavorare su Firebase, sarebbero entrambi utenti e porta- chiavi essere figlio di un nodo genitore "myparentnodename"?
  • Se modifico il database in questo modo, si sente altamente inefficiente perché ogni volta che interrogherò il nodo figlio "utenti" otterrei tutti gli utenti. O mi sbaglio? È possibile recuperare solo i dati corrispondenti a un utente specifico? Per esempio. ottenere l'utente dove "utente = utente1"? Possiamo fare query annidate? per esempio. combinare la condizione precedente con una condizione sulle chiavi della porta in modo che l'oggetto JSON restituito sia rilevante solo per le chiavi della porta contenute nel nodo "user1"?

enter image description here

risposta

10

Questa è una risposta molto lunga come la tua domanda era in realtà di circa 5 domande diverse.

nodo principale è: myparentnodename

Gli utenti

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 

e le chiavi

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

Con questa struttura, tutti gli elementi 'punto' a vicenda.

Se la tua ricerca uid_0 si può vedere che usano i tasti 0 e 3

Se si interroga Pulsante 3 si può vedere che appartengono ad utenti 0 e 2

La sua domanda era

ogni tempo vorrei interrogare il nodo figlio "utenti" Vorrei ottenere tutti gli utenti indietro

Questo è leggermente incompleto . Quando viene eseguita una query, di solito si esegue una query per qualcosa di specifico. Tuttavia, con Firebase, ci sono due modi per recuperare i dati: osservare un nodo e una query.

Se si desidera ripristinare tutti gli utenti nel nodo utenti, si osserverà tale nodo con .Value (o .ChildAdded per 1 alla volta).

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 
    } 
}) 

nota che quanto sopra attribuisce un osservatore al nodo utenti in modo eventuali future modifiche all'interno di tale nodo notificheranno l'applicazione e re-inviare l'intero nodo al app

Se si desidera solo uno informazioni dell'utente , e non vogliono continuare a guardare per le modifiche

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 
}) 

Infine, per interrogare per tutte le chiavi che appartengono al uid_0 (che è un po 'ridondante in questo esempio, poiché sappiamo già che le chiavi hanno dalla loro nodo) . Se le chiavi rif conteneva anche altre informazioni come il nome della porta, l'edificio la porta era in, o l'ubicazione porta, sarebbe più appropriato e richiederebbe una diversa struttura, in modo da assumere è questo il 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 
}) 

nota che questo codice è Swift poiché la piattaforma non è stata specificata nella domanda.

L'altra domanda:

Possiamo fare query nidificate? per esempio. combinare la condizione precedente con alcune condizioni sulle chiavi della porta in modo che l'oggetto JSON restituito sia solo relativo alle chiavi della porta contenute nel nodo "user1"?

Penso che intendi puoi interrogare per uid_2, vedere quali chiavi hanno e quindi caricare le informazioni da quelle chiavi specifiche.

Sì! Ma ... (c'è sempre un ma)

Firebase è asincrono quindi è necessario tenerne conto quando si annidano le query, ad esempio, è necessario assicurarsi che tutti i dati vengano restituiti prima di ottenere più dati. Ad esempio, se si desidera utilizzare i dati chiave di uid_2, è possibile osservareSingleEventOfType sul nodo uid_2. Avresti quindi le loro chiavi e potresti quindi osservareSingleEventOfType su ogni chiave.

Tecnicamente questo funziona, ma con dati asincroni che girano intorno, si potrebbe finire con il codice stomping su altro codice e l'elaborazione dei dati prima che sia effettivamente stato restituito.

L'opzione migliore (per il mio esempio) è quella di evitarlo completamente e interrogare il nodo delle chiavi per le chiavi di uid_2.

Come nota a margine, l'osservazione di un nodo ha un sovraccarico molto inferiore rispetto a una query, quindi se si desidera caricare un singolo nodo e si conosce il percorso, utilizzare osserva.