2

我想用集合來維護一些文件之間的關係,如here(但略有修改的方法)。我選擇了收集方法,因爲隨着時間的推移,文檔屬性似乎更具可擴展性。如何在firefire中綁定angularfire2中的多個查詢結果?

我的實際數據scructure

users 
    user1 
    user2 

companies 
    co1 
    co2 

user_co 
    user1 
     companies (collection) 
      co1 
      co2 

    user2 
     companies (collection) 
      co1 

但這種做法,我需要做多個查詢,以獲得所有可用的公司,因爲我們不能執行「IN」子句特定的用戶。

所以我需要在2個步驟檢索數據:

  1. 檢索公司用戶的名單有權訪問user_co/{user}/companies
  2. /companies/{id}

爲什麼2步獲得實際的公司?因爲我不想給所有用戶提供對所有公司的讀取訪問權限,並且查詢/companies會觸發訪問錯誤。

因此,我如何檢索從多個調用中檢索到的單個可綁定列表的文檔?

我有2個項目顯示在我的組件中,但字段值不顯示。我在檢索/公司文件的方式當然做錯了。

任何幫助將不勝感激。使用angularfire2 5.0.0-rc.3與火力4.5.2

回答

1

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

我終於改變了我的數據存儲到公司的FireStore的方式。

如提到的here以及與NoSQL相關的許多文檔中,非規範化是避免「加入」和多個查詢的方式。

使用非規範化可以將查詢所需的所有數據分組在一個地方。這通常意味着對於不同的查詢流程 ,將以不同的組合訪問相同的數據。因此我們 需要複製數據,這會增加總數據量。

這樣,我可以簡單地檢索/users/{user}/companies並獲取有關公司用戶所屬的所有相關信息。無論如何,無需爲所有用戶訪問所有公司信息(設置,用戶等)。

新的數據結構

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

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

安全規則,允許管理員邀請/添加用戶到公司

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

對口

當更新/companies/{company}/[name],我還需要檢索的所有用戶通過/companies/{company}/users屬於該公司,然後更新0中的所有文檔。這可以在一個transaction內完成。

相關問題