不允许重复记录

时间:2018-01-19 23:25:03

标签: firebase data-modeling firebase-security google-cloud-firestore

这是一个简单的检查,以限制重复的条目,我找不到办法,思考。

玛:

{
  "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"
    }
  }
}

1 个答案:

答案 0 :(得分:2)

使用当前架构实现这一目标并不是一个好方法。以下是两种方法,您可以进行不同的权衡。

反转数据模型

更改您的数据模型,使唯一性成为唯一选项,从而无需验证。

public class TestClass
{
    private readonly IOptionsSnapshot<AppConfiguration> _options;

    public TestClass(IOptionsSnapshot<AppConfiguration> optionsSnapshot)
    {
        _options = optionsSnapshot;
    }

    public SomeViewModel DoSomething()
    {
        // access the options
        var active = _options.Value.MQTTSettings.Active;

        // it’s fine to actively create *data* objects
        return new SomeViewModel()
        {
            IsActive = active,
        };
    }
}

请注意,在此模型中,您无法添加损坏的案例。

查询具有特定语言代码的任何文档,例如&#39;恩&#39;,你可以这样做:

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

优点:

  • 不可能使用非唯一语言代码
  • 易于实施

缺点:

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

后的验证

或者,您可以设置云功能以在任何写入时触发。然后,此函数可以使用代码为您执行唯一性强制执行。然后,如果它检测到问题,则会遵循您定义的某些逻辑,例如将文档标记为错误或删除&amp;记录后续的非唯一条目。

优点:

  • 您可以使用.where("En.name", ">", "") languages.unique_id.code
  • 执行复合索引

缺点:

  • 短时间内可能存在不正确的数据
  • 更难回复客户

更新后

不是允许客户端更新语言代码,而是要求他们写入子集合。让云功能在更新子集时触发,然后在主文档超过您的检查时更新主文档。 (可选)您可以删除子集合中的文档或将其保留为审计跟踪。

优点:

  • 您可以使用languages.unique_id.namelanguages.unique_id.code
  • 执行复合索引
  • 文档永远是正确的

缺点:

  • 文档中的数据可能会在短时间内失效
  • 更难回复客户