限制 Firebase 更新到自定义字段

huangapple go评论127阅读模式
英文:

Firebase limit update to a custom field

问题

以下是翻译好的内容:

在Firebase中,这是我的Firestore:

限制 Firebase 更新到自定义字段

我正在使用此函数来更新“喜欢”:

const docRef = await doc(db, "databasetest", "explaura");
const Path = `${_Selected.Name}.Like`;
await updateDoc(docRef, {
    [Path]: increment(1)
});

所以_Selected.Name是动态的(在截图上被引用为DynamicName)。

如何创建Firebase规则以仅允许“喜欢”更新?我找到了使用request.resource.data.keys().hasAll的解决方案,但它不起作用。我可以更新DynamicName的所有子项或不更新任何子项,但无法仅更新“喜欢”。请问您能帮助我吗?

我也尝试了类似以下的内容:

match /databasetest/explaura/{id}{
    allow read: if true;
    allow update: if (request.resource.data.diff(resource.data).affectedKeys().hasOnly(['Like']));
}
英文:

In Firebase, here is my Firestore :

限制 Firebase 更新到自定义字段

I am using this function to Update Like :

 const docRef = await doc(db, "databasetest", "explaura");
           const Path = `${_Selected.Name}.Like`;
            await updateDoc(docRef, {
                [Path]: increment(1)
            });

So _Selected.Name is Dynamic (Reference as DynamicName on the screen Shot).

How can I create a Firebase rules to allow ONLY like Update ? Found solution with request.resource.data.keys().hasAll but it's not Working. I can Update all child of DynamicName or none, but not Only "Like"

Can you help me please ?

I also Tried something like that :

match /databasetest/explaura/{id}{
      allow read: if true;
      allow update: if (request.resource.data.diff(resource.data).affectedKeys().hasOnly(['Like']));
    }

答案1

得分: 2

所有rules.MapDiff的方法返回一个不包含索引操作符的rules.Set,就像rules.List一样。这阻止了你用于你的目的(我大约两年前已经向Firebase提出了一个问题,希望他们将其添加到API中,但是至今没有任何消息,你可以自行创建一个)。

幸运的是,有一个已弃用的属性request.writeFields,你可以使用它,它符合你的需求。它包含了所有已更改的字段(已更新、已创建、已删除):

match /databasetest/explaura/{id}{
  allow read: if true;
  allow update: if request.writeFields.size() == 1  // 只更新一个字段
    && validate_update();

  function validate_update() {
    let fields = request.writeFields[0].split('.');  // 在你的情况下,request.writeFields应该等于['DynamicName.like']
    return fields.size() == 2    // ['DynamicName', 'like']
      && fields[0].size() <= 30  // 对DynamicName的某些条件
      && fields[1] == 'like'     // 更新的字段只有'like'
      && request.resource.data.get(fields, 0) = 1 + resource.data.get(fields, 0) // 我们只接受增量,可以根据需要进行修改
  }
}

在这里,我使用了接受数组作为参数的rules.Map.get版本来检索嵌套字段。

注意:

  1. request.writeFields已弃用,但仍在工作,使用时要小心。
  2. 我猜测它已弃用,因为它在某些边缘情况下的行为可能有点奇怪,特别是对于嵌套字段。
  3. 尽管如此,我觉得在没有提供相同功能的新解决方案的情况下将其标记为弃用有点荒谬(向Firebase团队打招呼吧...)。
英文:

All methods of rules.MapDiff return a rules.Set which does not contain an index operator, like rules.List does. This prevents using diff for your purpose (I have created a ticket to Firebase like 2 years ago to have this added to the API but haven't got any news since, feel free to create one yourself).

Fortunatly there is a deprecated property request.writeFields that you can use and that fits your need. It contains all the fields that have been changed (updated, created, deleted):

match /databasetest/explaura/{id}{
  allow read: if true;
  allow update: if request.writeFields.size() == 1  // Only one field is updated
    &amp;&amp; validate_update();

  function validate_update() {
    let fields = request.writeFields[0].split(&#39;\\.&#39;);  // In your case request.writeFields should be equal to [&#39;DynamicName.like&#39;]
    return fields.size() == 2    // [&#39;DynamicName&#39;,&#39;like&#39;]
      &amp;&amp; fields[0].size() &lt;= 30  // Some condition on DynamicName
      &amp;&amp; fields[1] == &#39;like&#39;     // Only field updated is &#39;like&#39;
      &amp;&amp; request.resource.data.get(fields, 0) = 1 + resource.data.get(fields, 0) // We only accept increment, modify as you wish
  }
}

Here I use the version of rules.Map.get accepting an array as parameter to retrieve nested fields.

Notes:

  1. request.writeFields is deprecated but still working, use at your own risk.
  2. My guess is that it has been deprecated because its behavior can be a bit weird in some edge cases, especially for nested fields.
  3. Still, I find it crazy to mark something as deprecated when there is no new solution offering the same functionality (heads up to the firebaser here...)

huangapple
  • 本文由 发表于 2023年3月9日 23:46:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/75686944.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定