2016-11-03 97 views
2

我有所謂的後一個目的:AngularFire2 - 推並從對象陣列刪除

constructor(
    public repliers: string[''], 
    public key: string = null 
) {} 

這裏是一個推手後的服務方法:

submitPost(post: Post) { 
    this.af.database.list('posts').push(post); 
} 

下面是其中所預訂的方法帖子表:

subscribeAllPosts(): Observable<Post[]> { 
    return this.af.database.list('posts') 
    .map(Post.fromJsonList); 
} 

在post類中,這裏是從json轉換它的靜態方法:

static fromJsonList(array:any): Post[] { 
    return array.map(Post.fromJson); 
} 

static fromJson({repliers, $key }:any): Post { 
    return new Post(repliers, $key); 
} 

當我提出它的工作原理後和火力點後的樣子:

posts 
    -> unique key 
      -> repliers 
        -> 0: '' 

當我依次通過我的職位,我提交一個後看到陣列與一個默認爲空的屬性鍵。

我想解決的問題是如何更新posts表中的帖子,以便能夠將額外的鍵推送到repliers數組並從數組中刪除。

一個問題是如何更新此列表而不替換整個事物,因爲其他用戶也可能正在添加/刪除它。謝謝

回答

1

解決此問題的正確方法是通過稱爲非規範化的過程輕微重構數據庫。

相反的帖子節點內嵌套「repliers」,你應該repliers存儲在它自己的根級別的節點,就像這樣:

/posts/$postKey/{data1, data2, ...} 
/post-repliers/$postKey/$replierKey/{data1, data2, ...} 

創建新的服務來管理崗位repliers。然後將該服務注入您的Posts服務。當您加載帖子時,您可以使用這項新服務來加載帖子回覆者。以下是這看起來可能:

public getPost(postKey: string): Observable<Post>{ 
    let postSubscription = <Observable<Post>> this.angularFire.database.object(`/posts/${postKey}`) 
     .map(this.mapPost); 
    let postRepliersSubscription = <Observable<PostReplier[]>> this.postReplierService.getRepliersForPost(postKey); 

    let postObservable = Observable.zip(postSubscription, postReplierSubscription).map((values) => { 
     if(values[0]) 
     values[0].repliers = values[1]; 
     return values[0]; 
    }); 

    return postObservable; 
    } 

在這個解決方案中,我們查詢火力的職位,以及repiers,然後返回一個新的observale,將等待所有查詢combinging兩個,並返回結果之前完成(發佈.replier集)。

當你同時需要兩個數據集時,這非常棒,但當然還有等待第二個查詢完成的性能。另一種方法是在返回前簡單地在帖子上保存修改者FirebaseListObservable。

爲什麼非規範化?

主要原因是安全性。 Firebase安全規則不允許您授予對某個媒體資源的寫入權限,並且拒絕其他媒體資源。當您授予寫入權限時,您可以爲整個節點及其所有子級執行此操作。

爲了解決這個問題,我們將一個ownerKey添加到Post對象,並且只允許其UID與ownerKey匹配的用戶修改Post對象。然後,通過將replierKey保存在post-repliers對象的路徑中,我們允許任何人回覆帖子,但用戶只能管理他們自己的post-replier對象。

例如,說我的UID是3498j3u9fjd0329,我可以創建在後回答者:

/post-repliers/$postKey/3498j3u9fjd0329

而是試圖在刪除其他用戶的回覆:

/post-repliers/$postKey/dzz09cu09j234f0

會返回權限被拒絕的錯誤。

下一步是什麼?

我建議你閱讀firebase denormalization here,因爲它可以幫助你理解如何更好地構建你的數據庫。

另請參閱Firebase安全規則文檔here。如果不是不可能的話,那麼結構不良的數據庫會使安全性變得非常困難。

祝你好運!