Wofür eignet sich der Firebase Firestore-Referenzdatentyp?


187

Ich erkunde gerade den neuen Firebase Firestore und er enthält einen Datentyp namens reference. Mir ist nicht klar, was das bewirkt.

  • Ist es wie ein Fremdschlüssel?
  • Kann damit auf eine Sammlung verwiesen werden, die sich an einer anderen Stelle befindet?
  • Wenn referencees sich um eine tatsächliche Referenz handelt, kann ich sie für Abfragen verwenden? Kann ich beispielsweise eine Referenz haben, die direkt auf den Benutzer verweist, anstatt die Benutzer-ID in einem Textfeld zu speichern? Und kann ich diese Benutzerreferenz zum Abfragen verwenden?

17
Ich denke, dieses Video vom Firebase-Team bricht es für Sie auf: youtube.com/watch?v=Elg2zDVIcLo (ab 4:36 Uhr)
Adarsh

Antworten:


88

Referenzen sind Fremdschlüsseln sehr ähnlich.

Die aktuell veröffentlichten SDKs können keine Verweise auf andere Projekte speichern. Innerhalb eines Projekts können Verweise auf jedes andere Dokument in einer anderen Sammlung verweisen.

Sie können Referenzen in Abfragen wie jeden anderen Wert verwenden: zum Filtern, Ordnen und zum Paging (startAt / startAfter).

Im Gegensatz zu Fremdschlüsseln in einer SQL-Datenbank sind Referenzen nicht hilfreich, um Verknüpfungen in einer einzelnen Abfrage durchzuführen. Sie können sie für abhängige Suchvorgänge verwenden (die wie Joins aussehen), aber seien Sie vorsichtig, da jeder Hop zu einem weiteren Roundtrip zum Server führt.


9
Können Sie mögliche Anwendungsfälle mitteilen? Ist es möglich, Felder in dieser Referenz abzufragen? ZB habe ich eine friendsSammlung, in der alle meine Freunde aufgelistet sind ( friends/myId). Dann verweise ich auf dieses Dokument im friendsFeld eines anderen Dokuments ( group/groupId). Ich möchte nur meine Freunde anzeigen, die zu dieser Gruppe gehören und so etwas tun : where('friends.myId', '==', true).
Wird

107
Übrigens kann es nützlich sein, die Dokumente zu aktualisieren , um ein Beispiel für das Hinzufügen eines Referenztyps aufzunehmen.
Wird

11
Ich kann keine Informationen dazu finden? Dies wird meine gesamte Datenbankstruktur ändern, ich muss mehr wissen ...
Ruben

3
Haben Sie ein Beispiel (vorzugsweise in Kürze) zum Abfragen mithilfe von Referenzen? Im Moment kann ich die rohe UID als String speichern, aber das scheint nicht richtig zu sein.
Mickey Cheong

6
Ich muss alle meine Referenztypen in Zeichenfolgen ändern, da die Abfragen bei einem Referenztyp immer fehlschlagen. Ich kann buchstäblich nichts darüber finden, wie man nach Referenztypen abfragt :( Wenn jemand herausfindet, wie man nach Referenztypen abfragt, lass es mich wissen ...
Sam Trent

131

Fügen Sie unten hinzu, was für mich unter Verwendung von Referenzen in Firestore funktioniert hat.

Wie die anderen Antworten sagen, ist es wie ein Fremdschlüssel. Das Referenzattribut gibt jedoch nicht die Daten des Referenzdokuments zurück. Zum Beispiel habe ich eine Liste von Produkten mit einer userRef-Referenz als eines der Attribute des Produkts. Wenn ich die Liste der Produkte erhalte, erhalte ich die Referenz des Benutzers, der das Produkt erstellt hat. Aber es gibt mir nicht die Details des Benutzers in dieser Referenz. Ich habe zuvor ein anderes Back-End als Dienste mit Zeigern verwendet, die ein "populate: true" -Flag haben, das die Benutzerdetails zurückgibt, anstatt nur die Referenz-ID des Benutzers, was hier großartig wäre (hoffentlich eine zukünftige Verbesserung) ).

Im Folgenden finden Sie einen Beispielcode, mit dem ich die Referenz festgelegt sowie die Produktkollektionsliste abgerufen und dann die Benutzerdetails aus der angegebenen Benutzerreferenz-ID abgerufen habe.

Legen Sie eine Referenz für eine Sammlung fest:

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

Holen Sie sich eine Sammlung (Produkte) und alle Referenzen zu jedem Dokument (Benutzerdetails):

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

Hoffe das hilft


3
Danke für das Teilen! Ich denke, es gibt einen Tippfehler in der ersten Zeile von Get part und es sollte sein db.collection('products').get(). Haben Sie versucht, Benutzer direkt zu bekommen? Ich newItem.userRef.get()db.collection("users").doc(newItem.userRef.id).get()
vermute, es

50
Zunächst einmal vielen Dank für das Beispiel. Ich hoffe, sie werden für die Zukunft ein "bevölkern: wahr" hinzufügen. Ansonsten ist das Speichern einer Referenz etwas sinnlos. Das gleiche hätte man tun können, indem man einfach das uidund die Referenz darüber speichert .
Jürgen Brandstetter

4
Danke für das Beispiel! Aber wozu wird der Referenztyp gespeichert, wenn beim Abfragen des Dokuments keine Option zum Auffüllen vorhanden ist? Wenn es eine Option zum Auffüllen gibt, die jemand kennt, lassen Sie es mich bitte wissen.
Harshil Shah

18
Tatsächlich ist es also kein Fremdschlüssel. Für mich macht es im Grunde nichts - was bringt es, referencewenn wir es nicht als echten Fremdschlüssel verwenden können?
Jean d'arme

14
Der einzige Vorteil von a referencegegenüber a stringist, dass Sie get()die Referenz direkt aufrufen können. Noch nicht sehr nützlich. Hoffe, sie fügen eine Option hinzu, um Referenzen automatisch mit den entsprechenden Objekten zu füllen!
Morgler

16

Für diejenigen, die nach einer Javascript-Lösung für die Abfrage nach Referenz suchen, besteht das Konzept darin, dass Sie in der Abfrageanweisung ein 'Dokumentreferenz'-Objekt verwenden müssen

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

(Ein großes Lob an die Antwort hier: https://stackoverflow.com/a/53141199/1487867 )

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.