不允许重复记录

Not allowed duplicate record

这是一个限制重复条目的简单检查,我想,我找不到办法做到这一点。

谢玛:

{
  "languages": {
    "unique_id": {
      "code": "Fr",
      "name": "French"
    },
    "unique_id": {
      "code": "En",
      "name": "English"
    }
  }
}

我试过的安全规则:

service cloud.firestore {
  match /databases/{database}/documents {
     match /languages/{language} {
      allow write: if !(resource.data.hasAny([request.resource.code]));
    }
  }
}

例如:不允许这样

{
  "languages": {
    "unique_id": {
      "code": "Fr",
      "name": "French"
    },
    "unique_id": {
      "code": "En",
      "name": "English"
    },
    "unique_id": {
      "code": "Fr",
      "name": "German"
    }
  }
}

在当前模式下确实没有好的方法。您可以探索以下 2 种具有不同权衡的方法。

反转数据模型

更改您的数据模型,使唯一性成为唯一选项,这样就无需进行验证。

{
  "languages": {
    "Fr": {
      "name": "French"
    },
    "En": {
      "name": "English"
    }
  }
}

请注意,在此模型中无法添加损坏的外壳。

查询具有特定语言代码的任何文档,例如'En',你可以这样做:

.where("En.name", ">", "")

优点:

  • 非唯一语言代码是不可能的
  • 易于实施

缺点:

  • 您将无法对语言代码或名称进行复合索引

Post-验证

或者,您可以设置 Cloud Functions 以在任何写入时触发。这个函数然后可以有代码来为你执行唯一性。如果它检测到问题,它将遵循您定义的一些逻辑,例如将文档标记为错误或删除并记录后续的非唯一条目。

优点:

  • 您可以使用 languages.unique_id.codelanguages.unique_id.name
  • 进行复合索引

缺点:

  • 不正确的数据可能会在短时间内存在
  • 更难将错误反馈给客户

Post-更新

不是让客户更新语言代码,而是要求他们写入子集合。让 Cloud Functions 触发对子集合的更新,然后在通过检查时更新主文档。然后,您可以选择删除子集合中的文档或将其保留为审计跟踪。

优点:

  • 您可以使用 languages.unique_id.codelanguages.unique_id.name
  • 进行复合索引
  • 文件永远正确

缺点:

  • 文档中的数据可能会在短时间内过时
  • 更难将错误反馈给客户