如何配置Firestore安全规则允许聊天伙伴更新对方用户文档?
AngularFire项目Firestore安全规则配置问题
背景与问题
我正在维护一个未做安全配置的Angular/Ionic项目,基于AngularFire开发。近期加固安全权限,限制用户仅能修改自身文档后,聊天功能出现异常:创建聊天消息时,应用通过批量写入更新双方用户文档,但非当前用户的文档更新操作始终失败。
批量写入代码如下:
const batch = this.db.firestore.batch(); const sellerUserDoc = this.db.firestore.collection(this.collectionId()).doc(this.toUserDocId(sellerExtendedUser)); batch.set(sellerUserDoc, this.createExtendedUserOfferConversationUpdateItem(sellerExtendedUser, offerConversation), { merge: true }); const buyerUserDoc = this.db.firestore.collection(this.collectionId()).doc(this.toUserDocId(buyerExtendedUser)); batch.set(buyerUserDoc, this.createExtendedUserOfferConversationUpdateItem(buyerExtendedUser, offerConversation), { merge: true }); return batch.commit();
需求
需要通过添加安全规则或修改查询/代码,实现存在对话关系的用户可互相写入对方文档。当前数据结构:
conversations集合:文档为随机ID,包含对话双方的buyerId和sellerId字段users集合:文档包含对话映射字段,但因安全规则限制,目前无法填充关联的对话ID
我尝试过多种规则配置均未成功,核心困境是:更新用户文档时无法获取对应的对话ID(已知Firestore安全规则不能充当数据过滤器)。
尝试过的非工作规则示例(本地模拟器测试)
match /users/{document=**} { allow write: if request.auth.uid == resource.data.id || isConvPartner(); allow read,update: if request.auth.uid == resource.data.id || getConversations(request.auth.uid) allow create: if request.auth != null; } function isConvPartner() { let isBuyer = get(/databases/staging-v1-conversations/documents).data.buyerId == request.auth.uid; let isSeller = get(/databases/staging-v1-conversations/documents/$(resource.data.id)).data.sellerId == request.auth.uid; return isBuyer || isSeller } function getConversations(uid){ let conversationsForuser = get(/databases/staging-v1-conversations/documents).data.values.buyerId.hasAny(uid); match /{prefix=**}/staging-v1-conversations/{docId} { allow read,write,update: if request.auth.uid == resource.data.buyerId || request.auth.uid == resource.data.sellerId || request.data.id == resource.data.id || get(/databases/staging-v1-conversations/documents/$(docId)).data.buyerId == request.auth.uid || get(/databases/staging-v1-conversations/documents/$(docId)).data.sellerId == request.auth.uid || resource == null || request.auth != null; allow create: if request.resource.data.buyerId == request.auth.uid || request.resource.data.sellerId == request.auth.uid; function recipeData() { return get(/databases/$(database)/documents/$(docId)).data.buyerId == request.auth.id } } return conversationsForuser }
更新的尝试
我尝试编写以下函数,希望允许更新对方用户文档,调用参数为登录用户ID和待更新用户ID:
function getConvForUser(loggedInId,userId){ let user = loggedInId; let userFetched = user-MYkirTsKsmCNevww40IzQpn0m6fX;//get(/databases/staging-v1-users/documents/$(user)); let conversationsList = userFetched.conversations.conversationsForuser0[0]; //get(/databases/staging-v1-conversations/documents/$(resource.data.conversations.keys()[0])).data.buyerId == request.auth.uid let conversations = "conversation-" + conversationsList; let conversationsForuser = get(/databases/staging-v1-conversations/documents/$(conversations)).buyerId.hasAny(userId); let conversationsForuser2 = get(/databases/staging-v1-conversations/documents/$(conversations)).sellerId.hasAny(userId); //let listOfConv = getAfter(/databases/staging-v1-conversations/documents).data.values.join(","); return conversationsForuser || conversationsForuser2 }
疑问
- 修改写入逻辑的思路是否可行?有没有无需修改规则就能实现互相写入的方法?
- 正确的Firestore安全规则应该如何编写,才能满足需求?
内容的提问来源于stack exchange,提问作者Vincent Gerris
相关产品推荐
相关产品推荐

