You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置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

}

疑问

  1. 修改写入逻辑的思路是否可行?有没有无需修改规则就能实现互相写入的方法?
  2. 正确的Firestore安全规则应该如何编写,才能满足需求?

内容的提问来源于stack exchange,提问作者Vincent Gerris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 14:50:26