2

Ich möchte eine Sammlung verwenden, um die Beziehung zwischen einigen Dokumenten zu halten, wie vorgeschlagen here (aber leicht modifizierten Ansatz). Ich habe den Sammlungsansatz gewählt, weil die Dokumenteigenschaften im Laufe der Zeit besser skalierbar erscheinen.Wie binden Sie mehrere Abfrageergebnisse in angularfire2 mit Firestore?

Meine aktuellen Daten scructure

users 
    user1 
    user2 

companies 
    co1 
    co2 

user_co 
    user1 
     companies (collection) 
      co1 
      co2 

    user2 
     companies (collection) 
      co1 

Aber mit diesem Ansatz, ich brauche mehrere Abfragen zu tun, um alle verfügbaren Unternehmen für einen bestimmten Benutzer zu erhalten, wie wir nicht „IN“ Klausel ausführen können.

Also muss ich Daten in zwei Schritten ab:

  1. abrufen Liste der Benutzer Unternehmen Zugriff haben in user_co/{user}/companies
  2. tatsächlichen Unternehmen abrufen von /companies/{id}

Warum zwei Schritte? Weil ich nicht allen Benutzern Lesezugriff auf alle Benutzer geben möchte und die Abfrage /companies würde dann Zugriffsfehler auslösen.

Also habe ich Schwierigkeiten damit, wie man eine einzelne bindbare Liste von Dokumenten abrufen kann, die von mehreren Anrufen abgerufen wurden?

Ich habe 2 Elemente in meiner Komponente angezeigt, aber Feldwerte werden nicht angezeigt. Ich mache sicherlich etwas falsch in der Art, wie ich Dokumente recherchiere.

Jede Hilfe würde sehr geschätzt werden.

MyService.ts

interface Company { 
    Name: string; 
    Owner: any; 
    id?: any; 
    time?: any; 
    creationTime?: any; 
} 

interface MyCompany { 
    id?: any; 
    Name: string; 
} 

@Injectable() 
export class CompanyService { 

    companiesCollection: AngularFirestoreCollection<Company>; 
    myCompaniesCollection: AngularFirestoreCollection<MyCompany>; 
    myCompanies; 

    constructor(private afs: AngularFirestore, private ats: AuthService) { 

     this.myCompaniesCollection = this.afs.collection('user_co').doc(this.ats.currentUserId).collection('companies'); 
     this.myCompanies = this.myCompaniesCollection.snapshotChanges().map(actions => { 
      return actions.map(a => { 
       // What is the good way to retrieve /companies data from here? 
       return this.afs.firestore.collection("companies").doc(a.payload.doc.id).get().then(doc => { 
        return { id: doc.id, ...doc.data() } 
       }).catch(error => { 
        console.log("Error reading company document:", error); 
       }); 
       // Original example that return data from /user_co 
       //return { id: a.payload.doc.id, ...a.payload.doc.data() } 
      }) 
     }); 
    } 

    getData() { 
     return this.myCompanies; 
    } 
} 

angularfire2 5.0.0-rc.3 mit Feuerbasis 4.5.2

Antwort

1

Ich habe mit geändert endlich so, wie ich Daten in Firestor speichern.

Wie erwähnt here und in vielen Docs im Zusammenhang mit NoSQL, Denormalisierung ist der Weg zu gehen, um "Join Like" und mehrere Abfragen zu vermeiden.

Mit Denormalisierung kann man Gruppe alle Daten, die benötigt wird, eine Abfrage an einem Ort zu verarbeiten. Dies bedeutet oft, dass für unterschiedliche Abfrageströme dieselben Daten in verschiedenen Kombinationen abgerufen werden. Daher müssen wir Daten duplizieren, was das gesamte Datenvolumen erhöht.

So kann ich einfach /users/{user}/companies abrufen und erhalten alle relevanten Informationen über Unternehmen Benutzer gehört. Außerdem müssen Sie nicht auf alle Unternehmensinformationen (Einstellungen, Benutzer usw.) für alle Benutzer zugreifen können.

Neue Datenstruktur

/users/{user} 
    user_name 
    /companies/{company} 
     company_name 

/companies/{company} 
    name 
    /admins/{user} 
    /users/{user} 
     user_name 

Sicherheitsregeln ermöglichen Administratoren Benutzer einladen/in den Unternehmen

match /users/{usr}/companies/{co} { 
    // Only visible to the actual user 
    allow read: if request.auth.uid == usr; 

    // Current user can opt-out of company 
    allow delete: if request.auth.uid == usr || 
     // Company admin can add or drop-out a user 
     exists(/databases/$(db)/documents/companies/$(co)/admins/$(request.auth.uid)); 

    // Company admin can add or drop-out a user 
    allow create, update: if exists(/databases/$(db)/documents/companies/$(co)/admins/$(request.auth.uid)); 
} 

match /companies/{co} { 
    // Company accessible for members and admins only 
    allow read: if 
     exists(/databases/$(db)/documents/companies/$(co)/members/$(request.auth.uid)) || 
      exists(/databases/$(db)/documents/companies/$(co)/admins/$(request.auth.uid)); 

    match /admins/{usr} { 
     // allow company creation if it does not exists 
     allow create: if exists(/databases/$(db)/documents/companies/$(co)) == false 
     // updates allowed for admins 
     allow update, delete: if exists(/databases/$(db)/documents/companies/$(co)/admins/$(request.auth.uid)); 
    } 
    match /users/{usr} { 
     // writes allowed for admins 
     allow write: if exists(/databases/$(db)/documents/companies/$(co)/admins/$(request.auth.uid)); 
    } 
} 

Partner

Wenn /companies/{company}/[name] aktualisieren, muss ich auch alle Benutzer abrufen das gehört zu dieser Firma durch /companies/{company}/users und aktualisieren Sie dann alle Dokumente in /users/{user}/companies/{company}. Dies kann innerhalb einer einzigen transaction gemacht werden.

Verwandte Themen