2017-10-05 38 views
0

我想在firebase firestore中存储一对多关系。假设我有一位作者,并且有属于这位作者的书籍。我可以将其存储在一个嵌套的关系:用firestore创建安全的类似REST的API

author/ 
    authorId1 : { 
    books: [{...}, {...}] 
    } 

但我也需要一种方法来列出所有的书籍,最好不通过每一个作者迭代(据我所知它被要求实时DB),所以我想我应该这样做

author/ 
    authorId1 : { 
    books: [bookId1, bookId2] 
    } 
books/ 
    bookId1: {...} 
    bookId2: {...} 

但出于安全和性能的原因,我宁愿不过滤前端。我发现这是可能的编写查询:

const bookRef = fireStore.collection('books'); 
debtorsRef.where('author', '==', authorId).then(...); 

这有望消除了性能问题,但它并不安全,因为它会是可以从客户端获取其他作者的书籍。另外,我宁愿将关系存储在作者文档中,而不是相反。

在例如Django Rest Framework的restful API上,我将查询设置为仅返回属于给定用户的书籍。 IIUC它可能与IAM,但基于这些例子,我不太清楚如何。

再说一遍,我想只有在作者的书籍属性中列出了它的id时才能返回该书。理论上一本书可能属于多个作者。

我想这是重复的,很多人都有这种担忧,但我无法找到明确的答案来解决这个特定的用例。

回答

1

你可以写Security Rules妥善保护您的查询:

service cloud.firestore { 
    match /databases/{database}/documents { 
    match /books/{bookId} { 
     allow read: if request.resource.data.author == resource.data.author 
    } 
    } 
} 

注意,目前我们只支持对等式(==)(!=<<=等)的限制,而不是不平等

您可以扩展此概念,以维护每本书子集合中的所有者列表,并执行存在检查(使用exists()函数):

service cloud.firestore { 
    match /databases/{database}/documents { 
    match /books/{bookId} { 
     allow read: if exists(/databases/$(database)/documents/books/$(bookId)/owners/$(request.auth.uid)) 
     match /owners/{ownerId} { 
     // Include other conditions that provide for ownership checks 
     allow write: if request.auth.uid == ownerId; 
     } 
    } 
    } 
} 
+0

所以如果我理解正确,目前没有办法检查作者是否拥有bookId。你如何表达多对一的关系,每本书可以属于多个用户? – fodma1

+0

更新了包含此信息的答案 –