A cosa serve il tipo di dati 'Reference' di Firebase Firestore?


189

Sto solo esplorando il nuovo Firebase Firestore e contiene un tipo di dati chiamato reference. Non mi è chiaro cosa faccia.

  • È come una chiave esterna?
  • Può essere utilizzato per indicare una raccolta che si trova altrove?
  • Se referenceè un riferimento effettivo, posso usarlo per le query? Ad esempio, posso avere un riferimento che punta direttamente all'utente, invece di memorizzare userId in un campo di testo? E posso utilizzare questo riferimento utente per le query?

18
Penso che questo video del team di Firebase lo scomponga per te: youtube.com/watch?v=Elg2zDVIcLo (guarda dalle 4:36)
Adarsh

Risposte:


91

I riferimenti sono molto simili alle chiavi esterne.

Gli SDK attualmente rilasciati non possono memorizzare riferimenti ad altri progetti. All'interno di un progetto, i riferimenti possono puntare a qualsiasi altro documento in qualsiasi altra raccolta.

È possibile utilizzare i riferimenti nelle query come qualsiasi altro valore: per filtrare, ordinare e per il paging (startAt / startAfter).

A differenza delle chiavi esterne in un database SQL, i riferimenti non sono utili per eseguire join in una singola query. Puoi usarli per ricerche dipendenti (che sembrano unirsi come), ma fai attenzione perché ogni hop si tradurrà in un altro round trip al server.


9
Per favore, puoi condividere possibili casi d'uso? È possibile interrogare i campi in quel riferimento? Ad esempio, ho una friendsraccolta che elenca tutti i miei amici ( friends/myId). Quindi, faccio riferimento a questo documento nel friendscampo di un altro documento ( group/groupId). Mi piacerebbe visualizzare solo i miei amici che sono in quel gruppo, fare qualcosa di simile: where('friends.myId', '==', true).
Sarà il

108
A proposito, potrebbe essere utile aggiornare i documenti per includere un esempio di aggiunta di un tipo di riferimento.
Sarà il

11
Non riesco a trovare alcuna informazione al riguardo? Questo cambierà tutta la mia struttura del database, ho bisogno di saperne di più ...
Ruben,

3
hai un esempio (preferibilmente in rapido) su come interrogare usando il riferimento? in questo momento, posso farlo memorizzando l'UID Raw come stringa, ma non sembra giusto.
Mickey Cheong,

6
Ho bisogno di cambiare tutti i miei tipi di riferimento in stringhe perché le query falliranno sempre con un tipo di riferimento. Non riesco letteralmente a trovare nulla su come eseguire una query in base al tipo di riferimento :( se qualcuno scopre come eseguire una query in base ai tipi di riferimento fammi sapere ...
Sam Trent,

133

Aggiungendo di seguito ciò che ha funzionato per me usando i riferimenti in Firestore.

Come dicono le altre risposte, è come una chiave esterna. L'attributo di riferimento non restituisce tuttavia i dati del documento di riferimento. Ad esempio, ho un elenco di prodotti, con un riferimento userRef come uno degli attributi sul prodotto. Ottenere l'elenco dei prodotti, mi dà il riferimento dell'utente che ha creato quel prodotto. Ma non mi fornisce i dettagli dell'utente in quel riferimento. Ho usato altri back-end come servizi con puntatori prima che hanno un flag "populate: true" che restituisce i dettagli dell'utente anziché solo l'id di riferimento dell'utente, che sarebbe bello avere qui (speriamo un miglioramento futuro ).

Di seguito è riportato un codice di esempio che ho usato per impostare il riferimento, nonché ottenere la raccolta della lista dei prodotti, quindi ottenere i dettagli dell'utente dall'ID di riferimento dell'utente fornito.

Imposta un riferimento su una raccolta:

let data = {
  name: 'productName',
  size: 'medium',
  userRef: db.doc('users/' + firebase.auth().currentUser.uid)
};
db.collection('products').add(data);

Ottieni una raccolta (prodotti) e tutti i riferimenti su ciascun documento (dettagli utente):

db.collection('products').get()
    .then(res => {
      vm.mainListItems = [];
      res.forEach(doc => {
        let newItem = doc.data();
        newItem.id = doc.id;
        if (newItem.userRef) {
          newItem.userRef.get()
          .then(res => { 
            newItem.userData = res.data() 
            vm.mainListItems.push(newItem);
          })
          .catch(err => console.error(err));
        } else {
          vm.mainListItems.push(newItem);  
        }

      });
    })
    .catch(err => { console.error(err) });

Spero che questo ti aiuti


3
Grazie per la condivisione! Penso che ci sia un refuso nella prima riga di Get part e dovrebbe esserlo db.collection('products').get(). Hai provato a ottenere l'utente direttamente? Immagino che newItem.userRef.get()dovrebbe funzionare invece didb.collection("users").doc(newItem.userRef.id).get()
Sergey Nefedyev il

53
Prima di tutto grazie per l'esempio. Spero che aggiungano un "popolare: vero" per il futuro. Altrimenti il ​​salvataggio di un riferimento è alquanto inutile. Lo stesso avrebbe potuto essere fatto semplicemente salvando uide facendo riferimento ad esso.
Jürgen Brandstetter,

4
Grazie per l'esempio! Ma qual è lo scopo di memorizzare il tipo di riferimento se non esiste un tipo di opzione "popola" quando interroghiamo il documento? Se esiste un'opzione di compilazione che qualcuno conosce, per favore fatemelo sapere.
Harshil Shah,

18
Quindi in realtà non è come una chiave esterna. Per me praticamente non fa nulla - che senso ha avere referencese non possiamo usarlo come una vera chiave esterna dovrebbe funzionare?
jean d'arme,

14
Quindi l'unico vantaggio di una referenceover a stringè che puoi chiamare get()direttamente il riferimento. Ancora non molto utile. Spero che aggiungano un'opzione per popolare automaticamente i riferimenti con gli oggetti corrispondenti!
Morgler,

16

Per coloro che cercano una soluzione Javascript per eseguire query per riferimento - il concetto è che, è necessario utilizzare un oggetto "riferimento documento" nell'istruzione query

teamDbRef = db.collection('teams').doc('CnbasS9cZQ2SfvGY2r3b'); /* CnbasS9cZQ2SfvGY2r3b being the collection ID */
//
//
db.collection("squad").where('team', '==', teamDbRef).get().then((querySnapshot) => {
  //
}).catch(function(error) {
  //
});

(Complimenti per la risposta qui: https://stackoverflow.com/a/53141199/1487867 )

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.